Uji angka untuk narsisme


53

Angka narsis adalah angka yang merupakan jumlah dari digitnya sendiri, masing-masing dinaikkan menjadi kekuatan jumlah digit.

Misalnya, ambil 153 (3 digit):

1 3 + 5 3 + 3 3 = 1 + 125 + 27 = 153

1634:

1 4 + 6 4 + 3 4 + 4 4 = 1 + 1296 + 81 + 256 = 1634

Tantangan:

Kode Anda harus mengambil input dari pengguna dan menghasilkan Benar atau Salah tergantung pada apakah nomor yang diberikan adalah Nomor Narsis.

Kesalahan memeriksa string teks atau input tidak valid lainnya tidak diperlukan. 1 atau 0 untuk output dapat diterima. Kode yang hanya menghasilkan daftar Nomor Narsis, atau memeriksa input pengguna terhadap daftar, tidak memenuhi syarat.

OEIS A005188


3
Apakah boleh jika saya mengeluarkan Truejika nomor tersebut, tetapi hal lain (dalam hal ini nomor itu sendiri) jika tidak?
devRicher

Jawaban:


39

APL (15)

∆≡⍕+/(⍎¨∆)*⍴∆←⍞

Keluaran 1jika benar dan 0jika salah.

Penjelasan:

  • ∆←⍞: baca baris (sebagai karakter), simpan di
  • (⍎¨∆)*⍴∆: mengevaluasi setiap karakter dan meningkatkannya ke kekuasaan⍴∆
  • ∆≡⍕+/: lihat apakah input sama dengan representasi string dari jumlah ini

9
apa yang baru saja saya baca
Jbwilliams1

4
@LagWagon Bahasa Tuhan
mulai

21

GolfScript, 16 karakter

~.`:s{48-s,?-}/!

Input harus diberikan pada STDIN, output adalah 0 atau 1 yang menunjukkan angka non-narsis / narsis.

Penjelasan kode:

~              # Evaluate the input to get a number
.              # Accumulator (initially the number itself)
`:s            # Convert number to string and assign to variable s
{              # Loop over characters of the string
  48-          # Reduce character value by 48
  s,           # Push length of input number
  ?            # Power
  -            # Subtract result from accumulator
}/
!              # Not! (i.e. iff accumulator was zero it was a narcissistic number)

Saya melakukan pengambilan ganda pada `` ~ .` `` tetapi tampaknya tidak mungkin untuk ditingkatkan. Bagus
Peter Taylor

15

Mathematica, 43 karakter

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]

14

Perl, 38 karakter

perl -lpe '$@=y///c;$s+=$_**$@for/./g;$_=$_==$s'

Implementasi yang cukup mudah.

Berikut versi yang sedikit berbeda yang cocok untuk 35 karakter:

perl -lpe '$@=y///c;$s+=$_**$@for/./g;$_-=$s'

Versi ini menghasilkan nilai yang salah jika inputnya narsis, jika tidak menghasilkan nilai sebenarnya (Perl-accept). Orang mungkin berpendapat bahwa versi mundur ini berada dalam batas-batas deskripsi tantangan, tetapi setelah refleksi saya memutuskan untuk tidak melakukannya. Saya tidak begitu ingin meningkatkan skor saya. Namun.


“Tidak perlu memeriksa string teks atau input tidak valid lainnya.” - Jadi mengapa tidak mengira input tersebut akan menjadi nomor yang valid, tanpa tertinggal baris baru? echo -n 153 | perl -pe '…'akan bekerja tanpa -l.
manatwork

Saya pikir selama Anda menentukan apa output benar dan salah Anda, itu harus legal
Cruncher

Tegasnya, kata-kata dari teks tantangan tidak meninggalkan sedikit ambiguitas untuk apa arti Benar / Salah atau 0/1, jadi saya akan membiarkan yang satu ini berlalu. Namun, skrip berbeda dengan panjang yang sama yang mengembalikan nilai narsisistik akan memiliki keuntungan.
Iszi

Gagasan yang sama tetapi lebih pendek:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 karakter

(".=+/@("."0^#))(1!:1)1

(1!:1)1 adalah input keyboard (mengembalikan string).

".mengonversi input ke nomor; "0menentukan peringkat (dimensi) 0, dengan kata lain, mengambil setiap karakter dan mengubahnya menjadi angka.

^adalah fungsi daya dan fungsi #panjang, sehingga mengambil setiap digit ke kekuatan panjang string (ekuivalen, jumlah digit).

+/hanya jumlah, dan =membandingkan jumlah dan jumlah.


2
"Kode Anda harus mengambil input dari pengguna dan menghasilkan Benar atau Salah tergantung pada apakah nomor yang diberikan adalah Nomor Narsis." (penekanan pada saya)
John Dvorak

@ JanDvorak masukan keyboard saya buruk - ditambahkan.
rasionalis

12

Ruby, 34 + 5 = 39

Dengan bendera baris perintah

ruby -nlaF|

Lari

p eval [$F,0]*"**#{~/$/}+"+"==#$_"

Output benar atau salah.


3
Ini mungkin bendera Ruby terbanyak yang pernah saya lihat di kode golf yang sah: P
Doorknob

11

R, 71 69 66 56 48

Dikurangi 8 byte berkat @Giuseppe ! Idenya adalah untuk melakukan pembagian integer sebelum operasi modulo.

i=nchar(a<-scan()):0;a==sum((a%/%10^i%%10)^i[1])

(3 tahun) versi lama dengan penjelasan yang sesuai:

i=nchar(a<-scan()):1;a==sum(((a%%10^i)%/%10^(i-1))^i[1])

a<-scan()mengambil nomor (integer, real, ...) sebagai input (katakanlah 153misalnya).
imenjadi vektor yang mengandung 3 to 1 (jumlah karakter amenjadi 3).
%%adalah vektor sehingga a%%10^iberarti amodulo 1000, 100 dan 10: karena itu memberi 153, 53, 3.
(a%%10^i)%/%10^(i-1)adalah pembagian bilangan bulat dari vektor tersebut dengan 100, 10, 1: oleh karena itu 1, 5, 3,.
Kami meninggikan itu dengan elemen pertama iyang merupakan jumlah karakter (di sini digit) a, yaitu 3, dengan demikian memberikan vektor yang berisi 1, 125, 27yang kita sumdan bandingkan a.


Apakah divisi integer selalu bulat? Jika tidak, Anda dapat mengalami masalah dengan mis. 370 (angka narsis) berubah menjadi 4,7,0 (yang akan mengembalikan false) atau 270 (non-narsis) berubah menjadi 3,7,0 (kembali benar).
Iszi

Divisi integer tidak bulat ... Divisi integer 370 oleh 100 adalah 3 dengan sisa 70 dan bukan 3,70.
plannapus

1
48 byte ... seseorang menabrak ini ke beranda!
Giuseppe

9

Python 3, 56 byte

Tidak terlalu membingungkan, tetapi solusi sederhana.

s = input()
print(int(s)==sum(int(c)**len(s)for c in s))

1
The [dan ]tidak diperlukan, dan Anda bisa drop ruang di depan forjuga, jadi:sum(int(c)**len(s)for c in s)
marinus

Itu luar biasa! Terima kasih atas tipnya.
danmcardle

1
Anda dapat menyimpan dua karakter dengan menghapus spasi di s = input()dan yang lain dengan memindahkan ini ke 2,7 di mana printbukan fungsi.
Ben

Poin bagus, diedit.
danmcardle

Saya pikir Anda harus menunjukkan bahwa menambahkan kawat gigi ke print(maka satu karakter lebih) akan membuat ini solusi Python 2.x dan Python 3.x yang valid.
Martin Thoma

8

PHP, 80 74 66 karakter

Solusi PHP yang sangat mudah:

<?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;

Diasumsikan error_reportingtidak termasuk pemberitahuan, jika tidak beberapa karakter tambahan akan diperlukan untuk menginisialisasi $s=0;dan $i=0.

Thx @manatwork untuk mempersingkat banyak karakter.


Jangan menetapkan $ a dan $ l dalam pernyataan terpisah. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;lebih pendek.
manatwork

Karena Anda sudah memiliki pernyataan yang menghasilkan pemberitahuan, tambahkan saja yang lain: hapus inisialisasi variabel kontrol loop. Menambah variabel kontrol loop juga tidak perlu menjadi pernyataan mandiri. Dan kawat gigi pasti tidak diperlukan: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
manatwork

@manatwork: Terima kasih atas sambutan hangat untuk codegolf :)
Vlad Preda

Dapat for(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
bermain golf

8

Dc: 48 karakter

[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p

Contoh dijalankan:

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '153'
1

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '1634'
1

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '2013'
0

Tidak pernah benar-benar digunakan dc, simpan untuk kesalahan ketik panik dalam upaya untuk menuliscd
Stan Strum

8

K, 24 23

{x=+/xexp["I"$'a]@#a:$x}

Dicukur 1 char dengan pemesanan ulang

{x=+/{x xexp#x}"I"$'$x}

8

R, 53 byte

sum(scan(t=gsub("(.)","\\1 ",x<-scan()))^nchar(x))==x

The gsubregex menyisipkan spasi di antara karakter, sehingga scanfungsi akan dapat membaca nomor menjadi vektor digit.


+1 saya tidak akan pernah berpikir untuk melakukan itu, ini brilian.
plannapus


6

Powershell, 75 63 62 60 58

Sunting: Diperbarui per komentar Iszi (catatan: ini dianggap $xtidak ada)

Edit: Menambahkan perubahan @ Danko.

[char[]]($x=$n=read-host)|%{$x-="$_*"*$n.length+1|iex};!$x

58 56 karakter

Jika input dibatasi hingga 10 digit (termasuk semua int32)

($x=$n=read-host)[0..9]|%{$x-="$_*"*$n.length+1|iex};!$x

Saya bertanya-tanya apakah seseorang akan melakukan PowerShell sebelum saya melakukannya.
Iszi

Simpan 12 karakter dengan menambahkan variabel lain $xdan gunakan +=untuk melakukan penjumlahan alih-alih measure -summenguji $x-eq$n.
Iszi

1
61 karakter:($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x
Danko Durbić

1
@ DankoDurbić, Bagus! Jenis paksaan sering berguna dengan kode golf PoSh. Saya hanya mendapatkan 62 ketika saya menjalankan'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

1
@Rynant Poin bagus. Saya menjalankan pemeriksaan panjang Anda di PowerShell dan datang dengan 62 juga. Saat menjalankan pemeriksaan panjang yang sama terhadap skrip aktual , muncul 61. Ini mungkin karena bagaimana PowerShell menangani ''yang Anda ganti ''. Saya mengambil skrip asli ke Excel untuk mengecek =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")dan mendapatkan 62 juga. Tentu saja, kita selalu dapat menghitungnya secara manual - tetapi siapa yang benar-benar melakukannya?
Iszi

5

Python 2.x - 51

Konsep yang sama dengan solusi crazedgremlin untuk Python 3.x:

s=input();print s==sum(int(c)**len(`s`)for c in`s`)

4

C - 97 93 karakter

a,b;main(c){scanf("%d",&c);b=c;for(;c;c/=10)a+=pow(c%10,(int)log10(b)+1);printf("%d",a==b);}

Dengan lekukan:

a,b;
main(c) { 
  scanf("%d",&c);
  b=c;
  for(;c;c/=10)
    a+=pow(c%10,(int)log10(b)+1);
  printf("%d",a==b);
}

2
Anda tidak harus mendefinisikan intvariabel global.
Konrad Borowski

Wow. Anda sedang membaca input argc.
SIGSTACKFAULT

Juga, tidak harus melakukan -lmpada waktu kompilasi +1 byte?
SIGSTACKFAULT

@ Blacksilver -lmflag tidak diperlukan untuk kompiler C89.
Josh

Aha. Pelajari hal baru setiap hari.
SIGSTACKFAULT

4

Delphi - 166

uses System.SysUtils,math;var i,r,l:integer;s:string;begin r:=0;readln(s);l:=length(s);for I:=1to l do r:=round(r+power(strtoint(s[i]),l));writeln(inttostr(r)=s);end.

Dengan indentasi

uses System.SysUtils,math;
var
  i,r,l:integer;
  s:string;
begin
  r:=0;
  readln(s);
  l:=length(s);
  for I:=1to l do
    r:=round(r+power(strtoint(s[i]),l));
  writeln(inttostr(r)=s);
end.


3

Haskell 2010 - 76 karakter

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x

1
Anda tidak boleh memposting jumlah ms untuk menjalankan kode, tetapi jumlah karakter yang Anda gunakan. ;)
pengguna tidak diketahui

3

Awk: 40 39 karakter

{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1

Contoh dijalankan:

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '153'
1

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '1634'
1

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '2013'
0

3

Bash, 64 karakter

for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1]

a = $ 1; p = $ {# a}; untuk ((; a> 0; a / = 10)); do s = $ ((s + (% 10) ** p)); selesai; echo $ ( (s == $ 1))


1
Anda menggunakan p variabel di satu tempat, jadi tidak perlu. Anda dapat memindahkan inisialisasi dari variabel ke dalam foruntuk cadangan yang terpisah ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
manatwork

1
Dengan memindahkan evaluasi ke dalam forsatu karakter yang lebih dapat dipersingkat: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
manatwork

Oh, penasaran! Saya mencoba sesuatu seperti itu, tetapi tidak berhasil. Penasaran apa yang salah.
pengguna tidak diketahui

3

Lua (101 karakter)

Lua tidak dikenal ringkas, tetapi bagaimanapun juga menyenangkan untuk mencoba.

for n in io.lines()do l,s=n:len(),0 for i=1,l do d=n:byte(i)s=s+(d-48)^l end print(s==tonumber(n))end

Perbaikan disambut baik.


Karena tidak diperlukan bahwa program Anda dapat menangani dan memproses daftar angka, saya tidak akan menggunakan byte untuk mengimplementasikan fungsi itu. Mengganti loop for n in io.lines()do [...]enddengan n=io.read()menyimpan beberapa byte ( TIO ).
Jonathan Frech

3

JavaScript - 70 58 karakter

for(i in a=b=prompt())b-=Math.pow(a[i],a.length)
alert(!b)

catatan:

Jika Anda menguji ini di konsol dev Anda di Stack Exchange, perlu diketahui bahwa ada sejumlah properti non-standar yang ditambahkan String.prototypeyang akan merusak solusi ini, seperti String.prototype.formatUnicorn. Pastikan untuk menguji di lingkungan yang bersih, seperti pada about:blank.


Saya menghitung 70 karakter di sana.
manatwork

@manatwork, whoops, lupa menghitung baris baru.
zzzzBov

Trik hebat pengurangan itu!
manatwork

2
selalu kembali trueuntuk saya, terlepas dari input
koko

@ koko, saya telah menambahkan catatan untuk menjelaskan mengapa Anda menerima hasil yang salah.
zzzzBov

3

Java - 84 byte

(a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

Versi non-lambda: 101 byte:

boolean n(String a,int l){int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}

Disebut seperti ini:

interface X {
    boolean n(String a, int l);
}

static X x = (a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

public static void main(String[] args) {
    System.out.println(n("153",3));
    System.out.println(n("1634",4));
    System.out.println(n("123",3));
    System.out.println(n("654",3));
}

Pengembalian:

true
true
false
false

Anda dapat menghapus tanda kurung di sekitar argumen lambda, a,l->bekerja persis sama.
FlipTack

Saya tahu Anda sudah menjawab ini hampir setahun yang lalu, tetapi Anda bisa bermain golf dua byte: (a,l)->bisa a->l->dan bytebisa int:a->l->{int s=0;for(int c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}
Kevin Cruijssen

3

Japt , 14 9 7 byte

¶ì_xpZÊ

Cobalah online


Penjelasan

Input bilangan bulat implisit U.

ì_

Konversikan Uke array angka ( ì), sampaikan melalui fungsi dan konversikan kembali ke integer setelah.

xpZÊ

Kurangi dengan penambahan ( x), naikkan setiap elemen ke kekuatan ( p) dari panjang ( Ê) array dalam proses.

Periksa apakah hasilnya sama dengan U.


Saya pikir ¥U¬®n pUlÃxakan bekerja selama 11 byte;)
Oliver

2

F # - 92 karakter

let n=stdin.ReadLine()
n|>Seq.map(fun x->pown(int x-48)n.Length)|>Seq.sum=int n|>printf"%b"

2

Common Lisp - 116 102 karakter

(defun f(m)(labels((l(n)(if(> n 0)(+(expt(mod n 10)(ceiling(log m 10)))(l(floor n 10)))0)))(= m(l m))))

Diformat:

(defun f(m)
  (labels((l(n)
            (if(> n 0)
               (+(expt(mod n 10)(ceiling(log m 10)))
                 (l(floor n 10)))
               0)))
    (=(l m)m)))

2

Smalltalk - 102 99 karakter

[:n|a:=n asString collect:[:e|e digitValue]as:Array.^n=(a collect:[:each|each raisedTo:a size])sum]

Di Workspace, kirim value:dengan nomor itu, dan Cetak.


2

C #, 117

using System.Linq;class A{int Main(string[] a){return a[0].Select(c=>c-'0'^a[0].Length).Sum()==int.Parse(a[0])?1:0;}}

2

Haskell, 68 66 byte

d 0=[]
d n=mod n 10:d(div n 10)
sum.(\a->map(^length a)a).d>>=(==)

Pemakaian:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.