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


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

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)

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[]

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.


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


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.


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.


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

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.


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

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}

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.


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


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

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

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

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.


3

Haskell 2010 - 76 Zeichen

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

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

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


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.


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.


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

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.


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"

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

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.


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 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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.