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

Iszi
sumber
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
marinus
sumber
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)
Howard
sumber
Saya melakukan pengambilan ganda pada `` ~ .` `` tetapi tampaknya tidak mungkin untuk ditingkatkan. Bagus
Peter Taylor
15

Mathematica, 43 karakter

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]
alephalpha
sumber
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.

kotak roti
sumber
“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.

rasionalis
sumber
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.

histokrat
sumber
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.

plannapus
sumber
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))
danmcardle
sumber
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.

Vlad Preda
sumber
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
manatwork
sumber
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}
tmartin
sumber
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.

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

Kona, 18

...

{x=+/(0$'u)^#u:$x}
tmartin
sumber
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
Berasal
sumber
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`)
pengguna1354557
sumber
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);
}
Josh
sumber
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.
Teun Pronk
sumber
4

05AB1E , 7 byte (Tidak bersaing)

DSDgmOQ

Cobalah online!

-2 byte terima kasih kepada @daHugLenny

Guci Gurita Ajaib
sumber
3
Anda dapat menggantinya §1ôdenganS
acrolith
3

Haskell 2010 - 76 karakter

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x
Nathan Baum
sumber
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
manatwork
sumber
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))

Pengguna tidak diketahui
sumber
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.

criptych berdiri bersama Monica
sumber
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.

zzzzBov
sumber
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
Hypino
sumber
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.

Shaggy
sumber
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"
Smetad Anarkist
sumber
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)))
Paul Richter
sumber
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.

Paul Richter
sumber
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;}}
Itu adalah Notalie.
sumber
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
Angs
sumber