Teste eine Zahl auf Narzissmus

53

Eine narzisstische Zahl ist eine Zahl, die die Summe ihrer eigenen Ziffern darstellt, wobei jede Zahl zur Potenz der Anzahl der Ziffern erhoben wird.

Nehmen Sie zum Beispiel 153 (3 Stellen):

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

1634

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

Die Herausforderung:

Ihr Code muss Eingaben vom Benutzer entgegennehmen und Wahr oder Falsch ausgeben, je nachdem, ob es sich bei der angegebenen Nummer um eine narzisstische Zahl handelt.

Eine Fehlerprüfung auf Textzeichenfolgen oder andere ungültige Eingaben ist nicht erforderlich. 1 oder 0 für die Ausgabe ist akzeptabel. Code, der lediglich eine Liste narzisstischer Zahlen generiert oder die Benutzereingabe mit einer Liste vergleicht, ist nicht geeignet.

OEIS A005188

Iszi
quelle
3
Ist es in Ordnung, wenn ich ausgebe, Trueob es sich um eine solche Nummer handelt, aber sonst noch etwas (in diesem Fall die Nummer selbst), wenn nicht?
devRicher

Antworten:

39

APL (15)

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

Gibt aus, 1ob true und 0false.

Erläuterung:

  • ∆←⍞: Lesen Sie eine Zeile (als Zeichen), speichern Sie in
  • (⍎¨∆)*⍴∆: bewerte jedes Zeichen in und hebe es an die Macht⍴∆
  • ∆≡⍕+/: Überprüfen Sie, ob die Eingabe der Zeichenfolgendarstellung der Summe dieser Werte entspricht
Marinus
quelle
9
Was habe ich gerade gelesen
Jbwilliams1
4
@LagWagon Gottes Sprache
Tomsmeding
21

GolfScript, 16 Zeichen

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

Die Eingabe muss auf STDIN erfolgen, die Ausgabe ist 0 oder 1, was eine nicht narzisstische / narzisstische Zahl angibt.

Erklärung des Codes:

~              # 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
quelle
Ich habe ein Double-Take über "~" gemacht, aber es scheint unmöglich zu sein, mich zu verbessern. Schön.
Peter Taylor
15

Mathematica, 43 Zeichen

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]
Alephalpha
quelle
14

Perl, 38 Zeichen

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

Eine ziemlich unkomplizierte Implementierung.

Hier ist eine etwas andere Version, die in 35 Zeichen passt:

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

Diese Version gibt einen falschen Wert aus, wenn die Eingabe narzisstisch ist, andernfalls gibt sie einen (von Perl akzeptierten) wahren Wert aus. Man könnte argumentieren, dass diese Rückwärtsversion innerhalb der Grenzen der Herausforderungsbeschreibung liegt, aber nach Überlegung habe ich mich dagegen entschieden. Ich bin nicht so verzweifelt, meine Punktzahl zu verbessern. Noch.

Brot-Box
quelle
"Eine Fehlerprüfung auf Textzeichenfolgen oder andere ungültige Eingaben ist nicht erforderlich." - Warum also nicht annehmen, dass die Eingabe eine gültige Zahl ohne Zeilenumbruch ist? echo -n 153 | perl -pe '…'wird funktionieren ohne -l.
Manatwork
Ich denke, solange Sie definieren, was Ihre wahren und falschen Ausgaben sind, sollte es legal sein
Cruncher
Streng genommen hinterlässt der Wortlaut des Aufforderungstextes ein wenig Unklarheit darüber, was Wahr / Falsch oder 0/1 bedeuten soll, also lasse ich diesen einen bestehen. Ein anderes Skript gleicher Länge, das für narzisstische Werte true zurückgibt, hätte jedoch den Vorteil.
Iszi
Gleiche Idee, aber kürzer:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210
13

J, 23 Zeichen

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

(1!:1)1 ist eine Tastatureingabe (die einen String zurückgibt).

".wandelt die Eingabe in eine Zahl um; "0Gibt einen Rang (eine Dimension) von 0 an, dh jedes Zeichen wird in eine Zahl umgewandelt.

^ist die Potenzfunktion und #ist die Längenfunktion, die jede Ziffer zur Potenz der Länge der Zeichenkette macht (entsprechend der Anzahl der Stellen).

+/ist nur Summe und =vergleicht die Summe und die Zahl.

rationalis
quelle
2
"Ihr Code muss Eingaben vom Benutzer entgegennehmen und Wahr oder Falsch ausgeben, je nachdem, ob es sich bei der angegebenen Zahl um eine narzisstische Zahl handelt." (Hervorhebung meiner)
John Dvorak
@ JanDvorak Meine schlecht hinzugefügte Tastatureingabe.
Rationalis
12

Rubin, 34 + 5 = 39

Mit Befehlszeilenflags

ruby -nlaF|

Lauf

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

Gibt true oder false aus.

Histokrat
quelle
3
Dies ist möglicherweise die Ruby-Flagge, die ich je in einem legitimen
Codegolf
11

R 71 69 66 56 48

Reduziert um 8 Bytes dank @Giuseppe ! Die Idee war, die Ganzzahldivision vor der Modulo-Operation durchzuführen.

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

(3 Jahre) alte Version mit entsprechender Erklärung:

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

a<-scan()Nimmt eine Zahl (Integer, Real, ...) als Eingabe (sagen wir 153für das Beispiel).
iwird zu einem Vektor mit 3 zu 1 (die Anzahl der Zeichen aist 3).
%%ist vektorisiert, a%%10^ibedeutet also amodulo 1000, 100 und 10: es gibt also 153, 53, 3.
(a%%10^i)%/%10^(i-1)ist die ganzzahlige Division dieses Vektors durch 100, 10, 1: daher 1, 5, 3.
Wir heben das auf, wobei das erste Element idie Anzahl der Zeichen (hier Ziffern) von ist a, dh 3, 1, 125, 27wir geben einen Vektor an, der das enthält , womit wir sumvergleichen a.

Plannapus
quelle
Rundet die Ganzzahldivision immer ab? Andernfalls könnten Sie auf Probleme stoßen, wenn z. B. 370 (eine narzisstische Zahl) in 4,7,0 (die falsch zurückliefern würde) oder 270 (nicht narzisstisch) in 3,7,0 (die wahr zurückliefern würde) umgewandelt werden.
Iszi
Ganzzahlige Division rundet nicht ... Die ganzzahlige Division von 370 durch 100 ist 3, der Rest von 70 und nicht 3,70.
Plannapus
1
48 Bytes ... jemand hat dies auf die Homepage gestoßen!
Giuseppe
9

Python 3, 56 Bytes

Nicht sehr verschleiert, aber eine einfache Lösung.

s = input()
print(int(s)==sum(int(c)**len(s)for c in s))
danmcardle
quelle
1
Die [und ]sind unnötig, und Sie können das Leerzeichen vor forauch fallen lassen, so:sum(int(c)**len(s)for c in s)
Marinus
Das ist großartig! Danke für den Tipp.
Danmcardle
1
Sie können zwei Zeichen speichern, indem Sie die Leerzeichen in s = input()und ein anderes entfernen, indem Sie dies auf 2.7 verschieben, wo printkeine Funktion vorhanden ist.
Ben
Guter Punkt, bearbeitet.
Danmcardle
Ich denke, Sie sollten darauf hinweisen, dass das Hinzufügen von geschweiften Klammern print(daher ein Zeichen mehr) dies zu einer gültigen Python 2.x- und Python 3.x-Lösung machen würde.
Martin Thoma
8

PHP, 80 74 66 Zeichen

Sehr einfache PHP-Lösung:

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

Es wird davon error_reportingausgegangen, dass keine Hinweise enthalten sind, da andernfalls einige zusätzliche Zeichen zum Initialisieren von $s=0;und erforderlich sind $i=0.

Vielen Dank an @manatwork, um viele Zeichen zu verkürzen.

Vlad Preda
quelle
Weisen Sie $ a und $ l nicht in separaten Anweisungen zu. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;ist kürzer.
Manatwork
Da Sie bereits eine Anweisung haben, die einen Hinweis generiert, fügen Sie einfach eine weitere hinzu: Entfernen Sie die Initialisierung der Regelungsvariablen. Das Inkrementieren der Regelungsvariablen muss auch keine eigenständige Anweisung sein. Und die Verstrebungen sind definitiv nicht benötigt: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
Handarbeit
@manatwork: Vielen Dank für das herzliche Willkommen bei Codegolf :)
Vlad Preda
Kann dazu golfen werdenfor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Jörg Hülsermann
8

Gleichstrom: 48 Zeichen

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

Probelauf:

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
Mann bei der Arbeit
quelle
Nie wirklich verwendet dc, außer für hektische Tippfehler beim Versuch zu schreibencd
Stan Strum
8

K 24, 23

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

1 Saibling mit Nachbestellung rasiert

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

R, 53 Bytes

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

Der gsubRegex fügt Leerzeichen zwischen die Zeichen ein, damit die scanFunktion die Zahl in einen Ziffernvektor einlesen kann.

Flodel
quelle
+1 Ich hätte nie gedacht, das zu tun, es ist brillant.
Plannapus
6

Kona, 18

...

{x=+/(0$'u)^#u:$x}
tmartin
quelle
6

Powershell, 75 63 62 60 58

Bearbeiten: Aktualisiert per @ Iszis Kommentar (Hinweis: Dies gilt für $xnicht existierende)

Bearbeiten: @ Danko Änderungen hinzugefügt.

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

58 56 Zeichen

Wenn die Eingabe auf 10 Stellen begrenzt ist (einschließlich aller int32)

($x=$n=read-host)[0..9]|%{$x-="$_*"*$n.length+1|iex};!$x
Rynant
quelle
Ich habe mich gefragt, ob jemand PowerShell machen würde, bevor ich es tat.
Iszi
Speichern Sie 12 Zeichen, indem Sie eine weitere Variable hinzufügen $xund +=zum Summieren verwenden, anstatt zu measure -sumtesten $x-eq$n.
Iszi
1
61 Zeichen:($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x
Danko Durbić
1
@ DankoDurbić, schön! Typenzwang ist beim PoSh-Code-Golfen oft nützlich. Ich bekomme nur 62, wenn ich laufe'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant
1
@ Rynant Guter Punkt. Ich habe Ihren Längencheck in PowerShell durchgeführt und auch 62 gefunden. Wenn Sie eine Längenüberprüfung ähnlich wie beim eigentlichen Skript ausführen, wird 61 angezeigt. Dies liegt wahrscheinlich daran, wie PowerShell mit den Elementen umgeht, durch ''die Sie ersetzt haben ''. Ich nahm das ursprüngliche Skript in Excel, um es zu überprüfen, =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")und bekam auch 62. Natürlich könnten wir es immer manuell zählen - aber wer macht das wirklich?
Iszi
5

Python 2.x - 51

Gleiches Konzept wie die Lösung von crazedgremlin für Python 3.x:

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

C - 97 93 Zeichen

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

Mit Einrückung:

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
quelle
2
Sie müssen keine intglobalen Variablen definieren .
Konrad Borowski
Woah. Sie lesen die Eingabe in argc.
SIGSTACKFAULT
Sollte es nicht erforderlich sein, -lmzur Kompilierungszeit +1 Byte zu zählen?
SIGSTACKFAULT
@Blacksilver Das -lmFlag wird für C89-Compiler nicht benötigt.
Josh
Aha. Lerne jeden Tag etwas Neues.
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.

Mit Einzug

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
quelle
4

05AB1E , 7 Bytes (nicht konkurrierend)

DSDgmOQ

Probieren Sie es online!

-2 Bytes dank @daHugLenny

Magische Kraken-Urne
quelle
3
Sie können §1ômitS
acrolith
3

Haskell 2010 - 76 Zeichen

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x
Nathan Baum
quelle
1
Sie sollten nicht die Anzahl der ms angeben, um den Code auszuführen, sondern die Anzahl der Zeichen, die Sie verwendet haben. ;)
Benutzer unbekannt
3

Awk: 40 39 Zeichen

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

Probelauf:

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
Mann bei der Arbeit
quelle
3

Bash, 64 Zeichen

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

a = $ 1; p = $ {# a}; für ((; a> 0; a / = 10)); do s = $ ((s + (a% 10) ** p)); done; echo $ ( (s == $ 1))

Benutzer unbekannt
quelle
1
Sie verwenden die Variable p an einer einzelnen Stelle, brauchen sie also nicht. Sie können die Initialisierung der Variablen a in die bewegen forihre einzelnen zu ersparen ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
Handarbeit
1
Durch Bewegen der Auswertung in das forkann ein Zeichen mehr verkürzt werden: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
Handarbeit
Oh neugierig! Ich habe so etwas versucht, aber es hat nicht funktioniert. Neugierig was schief gelaufen ist.
Benutzer unbekannt
3

Lua (101 Zeichen)

Lua ist nicht dafür bekannt, prägnant zu sein, aber es hat Spaß gemacht, es trotzdem zu versuchen.

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

Verbesserungen sind willkommen.

Criptychon steht bei Monica
quelle
Da es nicht erforderlich ist, dass Ihr Programm eine Liste von Zahlen verarbeiten kann, würde ich keine Bytes verwenden, um diese Funktionalität zu implementieren. Das Ersetzen der Schleife for n in io.lines()do [...]enddurch n=io.read()spart einige Bytes ( TIO ).
Jonathan Frech
3

JavaScript - 70 58 Zeichen

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

Hinweis:

Wenn Sie dies in Ihrer Entwicklerkonsole unter Stack Exchange testen, müssen Sie sich darüber im Klaren sein, dass eine Reihe von nicht standardmäßigen Eigenschaften hinzugefügt wurden String.prototype, die diese Lösung beeinträchtigen, z String.prototype.formatUnicorn. Stellen Sie sicher, dass Sie in einer sauberen Umgebung testen, z. B. auf about:blank.

zzzzBov
quelle
Ich zähle dort 70 Zeichen.
Manatwork
@manatwork, whoops, hat vergessen, die Zeilenumbrüche zu zählen.
zzzzBov
Toller Trick diese Dekrementierung!
Handarbeit
2
es kehrt immer truefür mich zurück, unabhängig von der Eingabe
Koko
@koko, ich habe eine Notiz hinzugefügt, um zu erklären, warum Sie falsche Ergebnisse erhalten.
zzzzBov
3

Java - 84 Bytes

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

Nicht-Lambda-Version: 101 Bytes:

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

So genannt:

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

Kehrt zurück:

true
true
false
false
Hypino
quelle
Sie können die Klammer um die Lambda-Argumente entfernen, a,l->funktioniert genauso.
FlipTack
Ich weiß, dass Sie dies vor fast einem Jahr beantwortet haben, aber Sie können zwei Bytes Golf spielen: (a,l)->Kann sein a->l->und bytekann sein 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 Bytes

¶ì_xpZÊ

Probieren Sie es online aus


Erläuterung

Implizite Eingabe einer Ganzzahl U.

ì_

Konvertieren Sie Uin ein Array von Ziffern ( ì), übergeben Sie es einer Funktion und konvertieren Sie es anschließend zurück in eine Ganzzahl.

xpZÊ

Reduzieren Sie xjedes Element durch Addition ( ) und erhöhen Sie dabei die Potenz ( p) der Länge ( Ê) des Arrays.

Überprüfen Sie, ob das Ergebnis genau gleich ist U.

Zottelig
quelle
Ich denke, ¥U¬®n pUlÃxwürde für 11 Bytes arbeiten;)
Oliver
2

F # - 92 Zeichen

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

Common Lisp - 116 102 Zeichen

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

Formatiert:

(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
quelle
2

Smalltalk - 102 bis 99 Zeichen

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

Senden value:Sie im Arbeitsbereich die Nummer und drucken Sie sie aus.

Paul Richter
quelle
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;}}
Es istNotALie.
quelle
2

Haskell, 68 66 Bytes

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

Verwendungszweck:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Angs
quelle