Prova un numero per narcisismo


53

Un numero narcisistico è un numero che è la somma delle proprie cifre, ognuna elevata alla potenza del numero di cifre.

Ad esempio, prendi 153 (3 cifre):

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

1634:

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

La sfida:

Il codice deve ricevere input dall'utente e generare True o False a seconda che il numero indicato sia un numero narcisistico.

Non è richiesto il controllo degli errori per stringhe di testo o altri input non validi. 1 o 0 per l'uscita è accettabile. Il codice che genera semplicemente un elenco di numeri narcisistici o verifica l'input dell'utente rispetto a un elenco non è idoneo.

OEIS A005188


3
Va bene se output Truese è un tale numero, ma qualcos'altro (in questo caso il numero stesso) in caso contrario?
devRicher

Risposte:


39

APL (15)

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

Emette 1se vero e 0se falso.

Spiegazione:

  • ∆←⍞: leggi una riga (come caratteri), memorizza in
  • (⍎¨∆)*⍴∆: valuta ogni personaggio e aumentalo al potere⍴∆
  • ∆≡⍕+/: vedi se l'ingresso è uguale alla rappresentazione in stringa della somma di questi

9
cosa ho appena letto
Jbwilliams1,

4
@LagWagon Lingua di Dio
tomsmeding

21

GolfScript, 16 caratteri

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

L'ingresso deve essere dato su STDIN, l'output è 0 o 1 che indica un numero non narcisistico / narcisistico.

Spiegazione del codice:

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

Ho fatto un doppio giro su `` ~. '' `` Ma sembra impossibile migliorare. Ben fatto.
Peter Taylor,

15

Mathematica, 43 caratteri

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

14

Perl, 38 caratteri

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

Un'implementazione piuttosto semplice.

Ecco una versione leggermente diversa che si adatta a 35 caratteri:

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

Questa versione genera un valore falso se l'input è narcisistico, altrimenti genera un valore vero (accettato dal Perl). Si potrebbe sostenere che questa versione arretrata rientri nei limiti della descrizione della sfida, ma dopo aver riflettuto ho deciso di non farlo. Non sono così disperato per migliorare il mio punteggio. Ancora.


"Non è richiesto il controllo degli errori per stringhe di testo o altri input non validi." - Quindi perché non supporre che l'input sarà un numero valido, senza trascinare la nuova riga? echo -n 153 | perl -pe '…'funzionerà senza -l.
arte

Penso che finché definisci quali sono i tuoi output veri e falsi, dovrebbe essere legale
Cruncher

A rigor di termini, la formulazione del testo della sfida lascia un po 'di ambiguità sul significato di Vero / Falso o 0/1, quindi lascerò passare questo. Una sceneggiatura diversa di uguale lunghezza che ritorna vera per i valori narcisistici avrebbe però il vantaggio.
Iszi,

Stessa idea ma più breve:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 caratteri

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

(1!:1)1 è l'input da tastiera (che restituisce una stringa).

".converte l'input in un numero; "0specifica un rango (dimensione) pari a 0, in altre parole, prendendo ciascun carattere e convertendolo in un numero.

^è la funzione di potenza ed #è la funzione di lunghezza, portando così ogni cifra alla potenza della lunghezza della stringa (equivalentemente, il numero di cifre).

+/è solo somma e =confronta la somma e il numero.


2
"Il tuo codice deve ricevere input dall'utente e generare True o False a seconda che il numero indicato sia un numero narcisistico." (enfasi mia)
John Dvorak,

@JanDvorak Il mio male - aggiunto l'input da tastiera.
rationalis,

12

Rubino, 34 + 5 = 39

Con flag della riga di comando

ruby -nlaF|

Correre

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

Emette vero o falso.


3
Questa potrebbe essere la maggior parte delle bandiere Ruby che io abbia mai visto in un codice golf legittimo: P
Maniglia della porta

11

R, 71 69 66 56 48

Ridotto di 8 byte grazie a @Giuseppe ! L'idea era di eseguire la divisione intera prima dell'operazione modulo.

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

(3 anni) versione precedente con spiegazione corrispondente:

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

a<-scan()accetta un numero (intero, reale, ...) come input (diciamo 153per l'esempio).
idiventa un vettore contenente 3 a 1 (il numero di caratteri di aessere 3).
%%è vettorializzato quindi a%%10^isignifica amodulo 1000, 100 e 10: quindi dà 153, 53, 3.
(a%%10^i)%/%10^(i-1)è la divisione intera di quel vettore 100, 10, 1: pertanto, 1, 5, 3.
Lo eleviamo con il primo elemento di icui è il numero di caratteri (qui cifre) di a, cioè 3, dando così un vettore contenente 1, 125, 27quello a cui ci sumconfrontiamo a.


La divisione intera viene sempre arrotondata per difetto? Altrimenti, potresti riscontrare problemi con ad esempio 370 (un numero narcisistico) che si trasforma in 4,7,0 (che restituirebbe un falso) o 270 (non narcisistico) che si trasforma in 3,7,0 (che restituisce vero).
Iszi,

La divisione intera non arrotonda ... La divisione intera di 370 per 100 è 3 con il resto di 70 e non 3.70.
plannapus,

1
48 byte ... qualcuno l'ha portato alla homepage!
Giuseppe,

9

Python 3, 56 byte

Non molto offuscata, ma una soluzione semplice.

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

1
Gli [e ]sono superflui e puoi anche lasciare spazio davanti for, quindi:sum(int(c)**len(s)for c in s)
marinus

È fantastico! Grazie per il consiglio.
danmcardle,

1
È possibile salvare due caratteri rimuovendo gli spazi in s = input()e un altro spostandolo su 2.7 dove printnon è una funzione.
Ben

Buon punto, modificato.
danmcardle,

Penso che dovresti sottolineare che l'aggiunta di parentesi graffe print(quindi un altro carattere) renderebbe questa una valida soluzione Python 2.xe Python 3.x.
Martin Thoma,

8

PHP, 80 74 66 caratteri

Soluzione PHP molto semplice:

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

Presuppone error_reportingche non includa gli avvisi, altrimenti saranno necessari alcuni caratteri extra per inizializzare $s=0;e $i=0.

Grazie a @manatwork per abbreviare molti caratteri.


Non assegnare $ ae $ l in istruzioni separate. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;è più corto.
arte

Poiché hai già un'istruzione che genera un avviso, basta aggiungerne un'altra: rimuovere l'inizializzazione della variabile di controllo del ciclo. Anche l'incremento della variabile di controllo del ciclo non deve essere un'istruzione autonoma. E non sono assolutamente necessarie le parentesi: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
arte

@manatwork: Grazie per il caloroso benvenuto a codegolf :)
Vlad Preda,

Può essere golfato a questofor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Jörg Hülsermann

8

Dc: 48 caratteri

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

Esecuzione di esempio:

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

Mai effettivamente utilizzato dc, salvo errori di battitura frenetici nel tentativo di scriverecd
Stan Strum

8

K, 24 23

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

Rasato 1 carattere con riordino

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

8

R, 53 byte

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

La gsubregex inserisce spazi tra i caratteri, in modo che la scanfunzione sia in grado di leggere il numero in un vettore di cifre.


+1 non avrei mai pensato di farlo, è geniale.
plannapus,


6

Powershell, 75 63 62 60 58

Modifica: aggiornato per il commento di @ Iszi (nota: conta su $xnon esistente)

Modifica: aggiunte le modifiche di @ Danko.

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

58 56 caratteri

Se l'input è limitato a 10 cifre (include tutte le int32)

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

Mi chiedevo se qualcuno avrebbe fatto PowerShell prima di me.
Iszi,

Salva 12 caratteri aggiungendo un'altra variabile $xe usando +=per fare il tuo sommario invece di measure -sumtestare $x-eq$n.
Iszi,

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

1
@ DankoDurbić, Nizza! La coercizione di tipo è spesso utile con il golf di codice PoSh. Ne ottengo solo 62 quando corro'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant il

1
@Rynant Buono punto. Ho eseguito il controllo della lunghezza in PowerShell e ne ho anche 62. Quando si esegue un controllo di lunghezza in modo simile rispetto allo script effettivo , viene visualizzato 61. Ciò è probabilmente dovuto al modo in cui PowerShell gestisce il dispositivo ''sostituito ''. Ho preso lo script originale in Excel per ricontrollare =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")e ho ottenuto anche 62. Certo, potremmo sempre contarlo manualmente - ma chi lo fa davvero?
Iszi,

5

Python 2.x - 51

Stesso concetto della soluzione crazedgremlin per Python 3.x:

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

4

C - 97 93 caratteri

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

Con rientro:

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
Non è necessario definire intper le variabili globali.
Konrad Borowski,

Woah. Stai leggendo l'input in argc.
SIGSTACKFAULT

Inoltre, non dovresti fare -lmal conteggio del tempo di compilazione +1 byte?
SIGSTACKFAULT

@Blacksilver il -lmflag non è richiesto per i compilatori C89.
Josh

Aha. Impara una cosa nuova ogni giorno.
SIGSTACKFAULT

4

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

Con trattino

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 caratteri

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

1
Non dovresti pubblicare il numero di ms per eseguire il codice, ma il numero di caratteri che hai usato. ;)
utente sconosciuto il

3

Awk: 40 39 caratteri

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

Esecuzione di esempio:

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 caratteri

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)); done; echo $ ( (s == $ 1))


1
Stai utilizzando la variabile p in un unico posto, quindi non è necessario. È possibile spostare l'inizializzazione di variabili in un forper risparmiare la sua parte ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
arte

1
Spostando la valutazione in forun altro carattere può essere abbreviato: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
arte

Oh, curioso! Ho provato qualcosa del genere, ma non ha funzionato. Curioso cosa è andato storto.
utente sconosciuto

3

Lua (101 caratteri)

Lua non è nota per essere concisa, ma è stato comunque divertente provare.

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

Miglioramenti benvenuti.


Poiché non è necessario che il programma sia in grado di gestire ed elaborare un elenco di numeri, non utilizzerei i byte per implementare tale funzionalità. Sostituendo il loop for n in io.lines()do [...]endcon si n=io.read()salvano alcuni byte ( TIO ).
Jonathan Frech,

3

JavaScript - 70 58 caratteri

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

Nota:

Se lo stai testando nella tua console di sviluppo su Stack Exchange, tieni presente che sono state aggiunte alcune proprietà non standard String.prototypeche interromperanno questa soluzione, ad esempio String.prototype.formatUnicorn. Assicurati di provare in un ambiente pulito, come ad esempio about:blank.


Conto 70 caratteri lì.
arte

@manatwork, whoops, ha dimenticato di contare la nuova riga.
zzzzBov,

Grande trucco quella decrementazione!
arte

2
ritorna sempre trueper me, indipendentemente dall'input
koko

@koko, ho aggiunto una nota per spiegare perché stai ricevendo risultati errati.
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);};

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

Chiamato così:

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

Ritorna:

true
true
false
false

È possibile rimuovere la parentesi attorno agli argomenti lambda, a,l->funziona esattamente allo stesso modo.
FlipTack

So che hai risposto a questa domanda quasi un anno fa, ma puoi giocare a golf due byte: (a,l)->può essere a->l->e bytepuò essere 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Ê

Provalo online


Spiegazione

Input implicito di numero intero U.

ì_

Converti Uin un array di cifre ( ì), passalo attraverso una funzione e converti indietro in un numero intero dopo.

xpZÊ

Ridurre di addizione ( x), elevando ciascun elemento alla potenza ( p) della lunghezza ( Ê) dell'array nel processo.

Controlla se il risultato è strettamente uguale a U.


Penso ¥U¬®n pUlÃxche funzionerebbe per 11 byte;)
Oliver,

2

F # - 92 caratteri

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

2

Lisp comune - 116 102 caratteri

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

formattato:

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

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

Nell'area di lavoro, inviare value:con il numero e stamparlo.


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

Uso:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.