Prueba un número para narcisismo


53

Un número narcisista es un número que es la suma de sus propios dígitos, cada uno elevado a la potencia del número de dígitos.

Por ejemplo, tome 153 (3 dígitos):

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

1634:

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

El reto:

Su código debe recibir información del usuario y generar Verdadero o Falso dependiendo de si el número dado es un Número Narcisista.

No se requiere la comprobación de errores para cadenas de texto u otras entradas no válidas. 1 o 0 para la salida es aceptable. El código que simplemente genera una lista de números narcisistas, o verifica la entrada del usuario en una lista, no califica.

OEIS A005188


3
¿Está bien si salgo Truesi es un número así, pero cualquier otra cosa (en este caso, el número en sí) si no?
devRicher

Respuestas:


39

APL (15)

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

Salidas 1si es verdadero y 0si es falso.

Explicación:

  • ∆←⍞: leer una línea (como caracteres), almacenar en
  • (⍎¨∆)*⍴∆: evaluar cada personaje y elevarlo al poder⍴∆
  • ∆≡⍕+/: ver si la entrada es igual a la representación de cadena de la suma de estos

99
¿Qué acabo de leer
Jbwilliams1

44
@LagWagon El lenguaje de Dios
tomsmeding

21

GolfScript, 16 caracteres

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

La entrada se debe dar en STDIN, la salida es 0 o 1 que indica un número no narcisista / narcisista.

Explicación del código:

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

Hice una doble toma de `` ~ .`` `pero parece imposible mejorar. Buena esa.
Peter Taylor

15

Mathematica, 43 caracteres

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

14

Perl, 38 caracteres.

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

Una implementación bastante sencilla.

Aquí hay una versión ligeramente diferente que cabe en 35 caracteres:

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

Esta versión genera un valor falso si la entrada es narcisista; de lo contrario, genera un valor verdadero (aceptado por Perl). Se podría argumentar que esta versión hacia atrás se encuentra dentro de los límites de la descripción del desafío, pero después de reflexionar, decidí no hacerlo. No estoy tan desesperado por mejorar mi puntaje. Todavía.


"No se requiere la comprobación de errores para cadenas de texto u otras entradas no válidas". Entonces, ¿por qué no suponer que la entrada será un número válido, sin seguir la nueva línea? echo -n 153 | perl -pe '…'funcionará sin -l.
trabajo de

Creo que siempre y cuando defina cuáles son sus resultados verdaderos y falsos, debería ser legal
Cruncher

Estrictamente hablando, la redacción del texto del desafío deja un poco de ambigüedad en cuanto a lo que debe significar Verdadero / Falso o 0/1, por lo que dejaré pasar este. Sin embargo, un guión diferente de igual longitud que devuelva verdadero para valores narcisistas tendría la ventaja.
Iszi

La misma idea pero más corto:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 caracteres

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

(1!:1)1 es entrada de teclado (devuelve una cadena).

".convierte la entrada a un número; "0especifica un rango (dimensión) de 0, en otras palabras, toma cada carácter y lo convierte en un número.

^es la función de potencia y #es la función de longitud, llevando así cada dígito a la potencia de la longitud de la cadena (equivalentemente, el número de dígitos).

+/es solo suma y =compara la suma y el número.


2
"Su código debe recibir información del usuario y generar Verdadero o Falso dependiendo de si el número dado es un Número Narcisista". (énfasis mío)
John Dvorak

@ JanDvorak Mi error: entrada de teclado agregada.
racionalis

12

Rubí, 34 + 5 = 39

Con banderas de línea de comando

ruby -nlaF|

correr

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

Salidas verdadero o falso.


3
Esta puede ser la mayoría de las banderas de Ruby que he visto en un código de golf legítimo: P
Pomo de la puerta

11

R, 71 69 66 56 48

¡Reducido en 8 bytes gracias a @Giuseppe ! La idea era realizar la división entera antes de la operación del módulo.

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

(3 años) versión anterior con la explicación correspondiente:

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

a<-scan()toma un número (entero, real, ...) como entrada ( 153por ejemplo, por ejemplo).
ise convierte en un vector que contiene 3 a 1 (el número de caracteres de aser 3).
%%está vectorizado, por lo que a%%10^isignifica amódulo 1000, 100 y 10: por lo tanto, da 153, 53, 3.
(a%%10^i)%/%10^(i-1)es la división entera de ese vector por 100, 10, 1: por lo tanto 1, 5, 3,.
Elevamos eso con el primer elemento icuyo es el número de caracteres (aquí dígitos) de a, es decir 3, dando así un vector 1, 125, 27que contiene sumy con el que se compara a.


¿La división entera siempre se redondea? De lo contrario, podría tener problemas con 370 (un número narcisista) que se convierte en 4,7,0 (que devolvería falso) o 270 (no narcisista) en 3,7,0 (que devuelve verdadero).
Iszi

La división de enteros no se redondea ... La división de enteros de 370 por 100 es 3 con el resto de 70 y no 3.70.
plannapus

1
48 bytes ... alguien lanzó esto a la página de inicio.
Giuseppe

9

Python 3, 56 bytes

No muy ofuscado, pero es una solución simple.

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

1
Los [y ]son innecesarios, y también puede soltar el espacio delante for, así que:sum(int(c)**len(s)for c in s)
marinus

¡Eso es genial! Gracias por el consejo.
danmcardle

1
Puede guardar dos caracteres eliminando los espacios s = input()y otro moviendo esto a 2.7 donde printno es una función.
Ben

Buen punto, editado.
danmcardle

Creo que debería señalar que agregar llaves print(por lo tanto, un carácter más) haría que esta sea una solución válida de Python 2.xy Python 3.x.
Martin Thoma

8

PHP, 80 74 66 caracteres

Solución PHP muy sencilla:

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

Asume error_reportingque no incluye avisos, de lo contrario se necesitarán bastantes caracteres adicionales para inicializar $s=0;y $i=0.

Thx @manatwork para acortar muchos caracteres.


No asigne $ a y $ l en declaraciones separadas. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;Es más corto.
manatwork

Como ya tiene una declaración que genera un aviso, simplemente agregue otra: elimine la inicialización de la variable de control de bucle. Incrementar la variable de control de bucle tampoco necesita ser una declaración independiente. Y, definitivamente, no son necesarios los apoyos: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
manatwork

@manatwork: Gracias por la cálida bienvenida a codegolf :)
Vlad Preda

Se puede jugar a estofor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Jörg Hülsermann

8

Dc: 48 caracteres

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

Ejecución de muestra:

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

En realidad nunca se usó dc, excepto por errores tipográficos frenéticos en un intento de escribircd
Stan Strum

8

K, 24 23

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

Afeitado 1 char con reordenamiento

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

8

R, 53 bytes

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

La gsubexpresión regular inserta espacios entre caracteres, de modo que la scanfunción podrá leer el número en un vector de dígitos.


+1 nunca hubiera pensado en hacer eso, es genial.
plannapus


6

Powershell, 75 63 62 60 58

Editar: actualizado según el comentario de @ Iszi (nota: esto cuenta con $xno existente)

Editar: Se agregaron los cambios de @ Danko.

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

58 56 caracteres

Si la entrada está limitada a 10 dígitos (incluye todos los int32)

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

Me preguntaba si alguien iba a hacer PowerShell antes que yo.
Iszi

Guarde 12 caracteres agregando otra variable $xy utilizándola +=para hacer la suma en lugar de measure -sumluego hacer la prueba $x-eq$n.
Iszi

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

1
@ DankoDurbić, ¡Qué bien! La coerción de tipos a menudo es útil con el código de golf PoSh. Aunque solo tengo 62 cuando corro'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

1
@Rynant Buen punto. Ejecuté su verificación de longitud en PowerShell y también obtuve 62. Cuando se ejecuta una comprobación de longitud similar al script real , aparece 61. Esto probablemente se deba a cómo PowerShell maneja el ''que reemplazó ''. Tomé el script original en Excel para verificarlo nuevamente =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")y obtuve 62 también. Por supuesto, siempre podríamos contarlo manualmente, pero ¿quién lo hace realmente?
Iszi

5

Python 2.x - 51

El mismo concepto que la solución de crazedgremlin para Python 3.x:

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

4

C - 97 93 caracteres

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 sangría:

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
No tiene que definir intpara variables globales.
Konrad Borowski

Woah Estás leyendo la entrada en argc.
SIGSTACKFAULT

Además, ¿no debería tener que hacerlo -lmen tiempo de compilación recuento +1 byte?
SIGSTACKFAULT

@Blacksilver, el -lmindicador no es necesario para los compiladores C89.
Josh

Ajá. Aprende algo nuevo todos los días.
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.

Con sangría

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 personajes

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

1
No debe publicar la cantidad de ms para ejecutar el código, sino la cantidad de caracteres que utilizó. ;)
usuario desconocido el

3

Awk: 40 39 caracteres

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

Ejecución de muestra:

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 caracteres

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

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


1
Está utilizando la variable p en un solo lugar, por lo que no es necesario. Puede mover la inicialización de una variable en el forque perder su separada ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
manatwork

1
Moviendo la evaluación en el foruno de los personajes más puede acortarse: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
manatwork

¡Oh curioso! Intenté algo así, pero no funcionó. Curioso lo que salió mal.
usuario desconocido el

3

Lua (101 caracteres)

Lua no es conocido por ser conciso, pero fue divertido intentarlo de todos modos.

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

Mejoras bienvenidas.


Como no es necesario que su programa pueda manejar y procesar una lista de números, no usaría bytes para implementar esa funcionalidad. Reemplazar el bucle for n in io.lines()do [...]endcon n=io.read()guarda algunos bytes ( TIO ).
Jonathan Frech

3

JavaScript - 70 58 caracteres

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

Nota:

Si está probando esto en su consola de desarrollo en Stack Exchange, tenga en cuenta que hay una serie de propiedades no estándar agregadas String.prototypeque romperán esta solución, como por ejemplo String.prototype.formatUnicorn. Asegúrese de realizar la prueba en un entorno limpio, como en about:blank.


Cuento 70 personajes allí.
manatwork

@manatwork, whoops, olvidó contar la nueva línea.
zzzzBov

¡Gran truco esa disminución!
manatwork

2
siempre vuelve truepara mí, independientemente de la entrada
koko

@koko, agregué una nota para explicar por qué recibes resultados incorrectos.
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);};

Versión no lambda: 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);}

Llamado así:

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

Devoluciones:

true
true
false
false

Puede eliminar el paréntesis alrededor de los argumentos lambda, a,l->funciona exactamente igual.
FlipTack

Sé que has respondido esto hace casi un año, pero puedes jugar dos bytes: (a,l)->puede ser a->l->y bytepuede ser 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Ê

Pruébalo en línea


Explicación

Entrada implícita de entero U.

ì_

Convierta Ua una matriz de dígitos ( ì), páselo a través de una función y vuelva a convertirlo en un entero después.

xpZÊ

Reduzca mediante la suma ( x), elevando cada elemento a la potencia ( p) de la longitud ( Ê) de la matriz en el proceso.

Compruebe si el resultado es estrictamente igual a U.


Creo ¥U¬®n pUlÃxque funcionaría para 11 bytes;)
Oliver

2

F # - 92 caracteres

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

2

Lisp común - 116 102 caracteres

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

Formateado:

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

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

En el espacio de trabajo, envíe value:con el número e imprímalo.


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

Uso:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.