Sprawdź liczbę pod kątem narcyzmu


53

Narcystyczne Liczba jest liczbą, która jest sumą swoich cyfr, każdy podniesiony do potęgi liczby cyfr.

Na przykład weź 153 (3 cyfry):

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

1634:

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

Wyzwanie:

Twój kod musi pobierać dane wejściowe od użytkownika i generować wartość Prawda czy Fałsz w zależności od tego, czy podana liczba jest liczbą narcystyczną.

Błąd sprawdzania ciągów tekstowych lub innych nieprawidłowych danych wejściowych nie jest wymagany. Dopuszczalne jest 1 lub 0 dla wyjścia. Kod, który po prostu generuje listę liczb narcystycznych lub sprawdza dane wejściowe użytkownika względem listy, nie kwalifikuje się.

OEIS A005188


3
Czy to w porządku, jeśli wypiszę, Truejeśli jest to taka liczba, ale cokolwiek innego (w tym przypadku sama liczba), jeśli nie?
devRicher

Odpowiedzi:


39

APL (15)

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

Wyprowadzane, 1jeśli prawda i 0jeśli fałsz.

Wyjaśnienie:

  • ∆←⍞: przeczytaj wiersz (jako znaki), zapisz w
  • (⍎¨∆)*⍴∆: oceń każdą postać i podnieś ją do władzy⍴∆
  • ∆≡⍕+/: sprawdź, czy dane wejściowe są równe reprezentacji ciągu ich sumy

9
co właśnie przeczytałem
Jbwilliams1

4
@LagWagon God language
tomsmeding

21

GolfScript, 16 znaków

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

Dane wejściowe należy podać na STDIN, wartość wyjściowa wynosi 0 lub 1, co oznacza liczbę nie narcystyczną / narcystyczną.

Objaśnienie kodu:

~              # 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)

Zrobiłem podwójne podejście do `` ~. '', Ale poprawa wydaje się niemożliwa. Niezłe.
Peter Taylor,


14

Perl, 38 znaków

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

Dość prosta implementacja.

Oto nieco inna wersja, która mieści 35 znaków:

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

Ta wersja generuje fałszywą wartość, jeśli dane wejściowe są narcystyczne, w przeciwnym razie generuje wartość (zaakceptowaną przez Perl). Można argumentować, że ta wsteczna wersja mieści się w granicach opisu wyzwania, ale po zastanowieniu postanowiłem tego nie robić. Nie jestem tak zdesperowany, aby poprawić swój wynik. Jeszcze.


„Błąd sprawdzania ciągów tekstowych lub innych nieprawidłowych danych wejściowych nie jest wymagany.” - Dlaczego więc nie założyć, że wprowadzony numer będzie prawidłowy, bez znaku nowej linii? echo -n 153 | perl -pe '…'będzie działać bez -l.
manatwork

Myślę, że dopóki zdefiniujesz, jakie są twoje prawdziwe i fałszywe wyniki, powinno to być legalne
Cruncher

Ściśle mówiąc, sformułowanie tekstu wyzwania pozostawia trochę niejasności co do tego, co powinno oznaczać prawda / fałsz lub 0/1, więc pozwolę temu przejść. Jednak inny skrypt o równej długości, zwracający wartość true dla wartości narcystycznych, miałby tę zaletę.
Iszi

Ten sam pomysł, ale krótszy:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 znaki

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

(1!:1)1 to wprowadzanie z klawiatury (zwracanie ciągu).

".konwertuje dane wejściowe na liczbę; "0określa stopień (wymiar) 0, innymi słowy, biorąc każdy znak i konwertując go na liczbę.

^jest funkcją potęgową i #jest funkcją długości, w ten sposób przenosząc każdą cyfrę do potęgi długości łańcucha (równoważnie liczby cyfr).

+/jest tylko sumą i =porównuje sumę i liczbę.


2
„Twój kod musi pobierać dane wejściowe od użytkownika i generować wartość Prawda czy Fałsz w zależności od tego, czy podana liczba jest liczbą narcystyczną.” (moje podkreślenie)
John Dvorak

@JanDvorak My bad - dodane wejście klawiatury.
rationalis

12

Rubin, 34 + 5 = 39

Z flagami wiersza poleceń

ruby -nlaF|

Biegać

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

Zwraca true lub false.


3
To mogą być najbardziej rubinowe flagi, jakie kiedykolwiek widziałem w legalnym kodzie golfowym: P
Klamka

11

R, 71 69 66 56 48

Zmniejszony o 8 bajtów dzięki @Giuseppe ! Pomysł polegał na przeprowadzeniu podziału liczb całkowitych przed operacją modulo.

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

(3-letnia) stara wersja z odpowiednim wyjaśnieniem:

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

a<-scan()przyjmuje liczbę (całkowitą, rzeczywistą, ...) jako dane wejściowe (powiedzmy 153na przykład).
istaje się wektorem zawierającym od 3 do 1 (liczba znaków wynosząca a3).
%%jest wektoryzowany, co a%%10^ioznacza amodulo 1000, 100 i 10: dlatego daje 153, 53, 3.
(a%%10^i)%/%10^(i-1)jest całkowitym podziałem tego wektora przez 100, 10, 1: dlatego też 1, 5, 3.
Podnosimy to, przy czym pierwszym elementem ijest liczba znaków (tutaj cyfr) a, tj. 3Dając w ten sposób wektor zawierający 1, 125, 27to, co my sumi porównujemy a.


Czy podział liczb całkowitych zawsze zaokrągla w dół? W przeciwnym razie możesz napotkać problemy, np. 370 (liczba narcystyczna) zmienia się w 4,7,0 (co zwróci fałsz) lub 270 (nie narcystyczny) zamienia się w 3,7,0 (zwracanie prawdy).
Iszi

Dzielenie liczb całkowitych nie zaokrągla ... Dzielenie liczb całkowitych 370 przez 100 wynosi 3, a pozostałe 70, a nie 3,70.
plannapus

1
48 bajtów ... ktoś trafił to na stronę główną!
Giuseppe,

9

Python 3, 56 bajtów

Niezbyt zaciemnione, ale proste rozwiązanie.

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

1
[I ]są niepotrzebne i można upuścić przestrzeń przed forzbyt, więc:sum(int(c)**len(s)for c in s)
Marinus

To cudownie! Dzięki za wskazówkę.
danmcardle

1
Możesz zapisać dwie postacie, usuwając spacje, s = input()a drugą, przenosząc ją na 2.7, gdzie printnie jest funkcją.
Ben

Dobry punkt, zredagowany.
danmcardle,

Myślę, że powinieneś zaznaczyć, że dodanie nawiasów klamrowych print(a więc o jeden znak więcej) sprawiłoby, że jest to prawidłowe rozwiązanie dla Python 2.xi Python 3.x.
Martin Thoma,

8

PHP, 80 74 66 znaków

Bardzo proste rozwiązanie PHP:

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

Zakłada się, error_reportingże nie zawiera powiadomień, w przeciwnym razie do zainicjowania $s=0;i potrzeba będzie kilku dodatkowych znaków $i=0.

Dzięki @manatwork za skrócenie wielu znaków.


Nie przypisuj $ ai $ l w osobnych instrukcjach. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;jest krótszy.
manatwork

Ponieważ masz już instrukcję generującą powiadomienie, po prostu dodaj inną: usuń inicjalizację zmiennej sterującej pętli. Zwiększanie zmiennej sterującej pętli również nie musi być samodzielną instrukcją. I szelki są na pewno nie jest potrzebny: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
manatwork

@manatwork: Dziękujemy za ciepłe powitanie w codegolf :)
Vlad Preda

Można w to for(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
zagrać w

8

Dc: 48 znaków

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

Przykładowy przebieg:

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

Nigdy nie używane dc, z wyjątkiem szalonych literówek w próbie pisaniacd
Stan Strum

8

K, 24 23

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

Ogolono 1 znak przy zmianie kolejności

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

8

R, 53 bajty

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

Wyrażenie gsubregularne wstawia spacje między znakami, dzięki czemu scanfunkcja będzie mogła odczytać liczbę do wektora cyfr.


+1 nigdy bym nie pomyślał o zrobieniu tego, jest genialny.
plannapus


6

PowerShell, 75 63 62 60 58

Edycja: Zaktualizowana według komentarza @ Iszi (uwaga: liczy się to, że $xnie istnieje)

Edycja: Dodano zmiany @ Danko.

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

58 56 znaków

Jeśli wprowadzanie jest ograniczone do 10 cyfr (obejmuje wszystkie liczby int32)

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

Zastanawiałem się, czy ktoś jeszcze nie zrobił PowerShell.
Iszi

Zapisz 12 znaków, dodając inną zmienną $xi +=wykonując sumowanie zamiast measure -sumtestować $x-eq$n.
Iszi

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

1
@ DankoDurbić, Nicea! Koercja typów często przydaje się w golfa PoSh. Dostaję tylko 62, gdy biegam'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

1
@Rynant Dobry punkt. Sprawdziłem twoją długość w PowerShell i wymyśliłem również 62. Podczas uruchamiania sprawdzania długości podobnie do rzeczywistego skryptu pojawia się 61. Prawdopodobnie wynika to z tego, w jaki sposób program PowerShell obsługuje ''zastąpiony skrypt ''. Wziąłem oryginalny skrypt do Excela, aby sprawdzić dwukrotnie, =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")i dostałem również 62. Oczywiście zawsze możemy to policzyć ręcznie - ale kto tak naprawdę to robi?
Iszi

5

Python 2.x - 51

Ta sama koncepcja, co rozwiązanie crazedgremlin dla Pythona 3.x:

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

4

C - 97 93 znaków

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);}

Z wcięciem:

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
Nie musisz definiować intzmiennych globalnych.
Konrad Borowski,

Łał Odczytujesz dane wejściowe do argc.
SIGSTACKFAULT

Ponadto, czy nie trzeba robić -lmw czasie kompilacji liczenia +1 bajt?
SIGSTACKFAULT

@Blacksilver -lmflaga nie jest wymagana w przypadku kompilatorów C89.
Josh

Aha. Naucz się nowej rzeczy każdego dnia.
SIGSTACKFAULT

4

Delfy - 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.

Z wcięciem

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 znaków

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

1
Nie powinieneś podawać liczby ms do uruchomienia kodu, ale liczbę użytych znaków. ;)
użytkownik nieznany

3

Awk: 40 39 znaków

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

Przykładowy przebieg:

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 znaki

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

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


1
Używasz zmiennej p w jednym miejscu, więc jej nie potrzebujesz. Można przenieść inicjalizacji zmiennej A do foroszczędzić swoim jednostkowym ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
manatwork

1
Przesuwając ocenę w forwięcej charakteru jednego może być skrócona: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
manatwork

Och, ciekawy! Próbowałem czegoś takiego, ale to nie zadziałało. Ciekawe, co poszło nie tak.
użytkownik nieznany

3

Lua (101 znaków)

Lua nie jest znana z tego, że jest zwięzła, ale i tak fajnie było spróbować.

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

Ulepszenia mile widziane.


Ponieważ nie jest wymagane, aby Twój program mógł obsługiwać i przetwarzać listę liczb, nie użyłbym bajtów do wdrożenia tej funkcji. Wymiana pętlę for n in io.lines()do [...]endz n=io.read()oszczędza kilka bajtów ( TiO ).
Jonathan Frech,

3

JavaScript - 70 58 znaków

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

Uwaga:

Jeśli testujesz to w konsoli deweloperskiej na Stack Exchange, pamiętaj, że dodano wiele niestandardowych właściwości String.prototype, które złamią to rozwiązanie, takie jak String.prototype.formatUnicorn. Testuj w czystym środowisku, takim jak na about:blank.


Naliczyłem tam 70 znaków.
manatwork

@manatwork, ups, zapomniałem policzyć nowy wiersz.
zzzzBov

Świetna sztuczka to zmniejszanie!
manatwork

2
zawsze truedo mnie wraca , bez względu na dane wejściowe
koko

@koko, dodałem notatkę wyjaśniającą, dlaczego otrzymujesz nieprawidłowe wyniki.
zzzzBov,

3

Java - 84 bajty

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

Wersja inna niż lambda: 101 bajtów:

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

Nazywany tak:

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));
}

Zwroty:

true
true
false
false

Możesz usunąć nawias wokół argumentów lambda, a,l->działa dokładnie tak samo.
FlipTack,

Wiem, że odpowiedziałeś na to prawie rok temu, ale możesz (a,l)->a->l->byteinta->l->{int s=0;for(int c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}
zagrać w

3

Japt , 14 9 7 bajtów

¶ì_xpZÊ

Wypróbuj online


Wyjaśnienie

Domniemane wprowadzenie liczby całkowitej U.

ì_

Konwertuj Una tablicę cyfr ( ì), przekaż ją przez funkcję i po niej przekonwertuj z powrotem na liczbę całkowitą.

xpZÊ

Zmniejsz przez dodanie ( x), podnosząc każdy element do potęgi ( p) długości ( Ê) tablicy w procesie.

Sprawdź, czy wynik jest ściśle równy U.


Myślę, ¥U¬®n pUlÃxże zadziałałoby na 11 bajtów;)
Oliver

2

F # - 92 znaki

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 znaków

(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))))

Sformatowany:

(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 znaków

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

W obszarze roboczym wyślij value:z numerem i wydrukuj go.


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 bajtów

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

Stosowanie:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.