Teste um número de narcisismo


53

Um número narcisista é um número que é a soma de seus próprios dígitos, cada um deles elevado à potência do número de dígitos.

Por exemplo, use 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

O desafio:

Seu código deve receber a entrada do usuário e gerar True ou False, dependendo de o número fornecido ser um número narcisista.

A verificação de erros para cadeias de texto ou outras entradas inválidas não é necessária. 1 ou 0 para a saída é aceitável. O código que simplesmente gera uma lista de Narcisistic Numbers ou verifica a entrada do usuário em uma lista não se qualifica.

OEIS A005188


3
Tudo bem se eu emitir Truese for um número assim, mas qualquer outra coisa (nesse caso, o próprio número), se não?
precisa saber é o seguinte

Respostas:


39

APL (15)

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

Saídas 1se true e 0false.

Explicação:

  • ∆←⍞: leia uma linha (como caracteres), armazene em
  • (⍎¨∆)*⍴∆: avaliar cada personagem e elevá-lo ao poder⍴∆
  • ∆≡⍕+/: veja se a entrada é igual à representação de string da soma desses

9
O que acabei de ler
Jbwilliams1

4
@LagWagon God language
tomsmeding

21

GolfScript, 16 caracteres

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

A entrada deve ser fornecida no STDIN, a saída é 0 ou 1, indicando um número não-narcísico / narcísico.

Explicação do 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)

Eu dei uma olhada dupla em `` ~. `` `Mas parece impossível melhorar. Agradável.
Peter Taylor

15

Mathematica, 43 caracteres

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

14

Perl, 38 caracteres

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

Uma implementação bastante direta.

Aqui está uma versão ligeiramente diferente que cabe em 35 caracteres:

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

Esta versão gera um valor falso se a entrada é narcisista, caso contrário, gera um valor verdadeiro (aceito por Perl). Pode-se argumentar que esta versão reversa se enquadra nos limites da descrição do desafio, mas, após reflexão, decidi não fazê-lo. Não estou tão desesperada para melhorar minha pontuação. Ainda.


“A verificação de erro para cadeias de texto ou outras entradas inválidas não é necessária.” - Então, por que não supor que a entrada será um número válido, sem seguir a nova linha? echo -n 153 | perl -pe '…'vai funcionar sem -l.
manatwork

Eu acho que desde que você definir o que seus verdadeiros e falsos saídas são, deve ser legal
Cruncher

Estritamente falando, a redação do texto do desafio deixa um pouco de ambiguidade sobre o que True / False ou 0/1 deve significar, portanto, deixarei passar esse. Um script diferente de comprimento igual que retorne verdadeiro para valores narcísicos teria a vantagem, no entanto.
Iszi

Mesma idéia, mas mais curto:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210

13

J, 23 caracteres

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

(1!:1)1 é a entrada do teclado (retornando uma sequência).

".converte entrada em um número; "0especifica uma classificação (dimensão) de 0, em outras palavras, pegando cada caractere e convertendo-o em um número.

^é a função de potência e #é a função de comprimento, levando cada dígito à potência do comprimento da sequência (equivalentemente, o número de dígitos).

+/é apenas soma e =está comparando a soma e o número.


2
"Seu código deve receber a entrada do usuário e gerar True ou False, dependendo de o número fornecido ser um número narcisista." (ênfase meu)
John Dvorak

@JanDvorak Minha entrada de teclado com adição ruim.
racionalis

12

Ruby, 34 + 5 = 39

Com sinalizadores de linha de comando

ruby -nlaF|

Corre

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

Saídas verdadeiras ou falsas.


3
Este pode ser o mais bandeiras rubi que eu já vi em um golf código legítimo: P
Doorknob

11

R, 71 69 66 56 48

Reduzido em 8 bytes graças a @ Giuseppe ! A idéia era realizar a divisão inteira antes da operação do módulo.

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

Versão antiga (de 3 anos) com explicação correspondente:

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

a<-scan()recebe um número (inteiro, real, ...) como entrada (digamos, 153por exemplo).
itorna-se um vetor contendo 3 a 1 (o número de caracteres asendo 3).
%%é vetorizado, então a%%10^isignifica amódulo 1000, 100 e 10: portanto, dá 153, 53, 3.
(a%%10^i)%/%10^(i-1)é a divisão inteira desse vetor por 100, 10, 1: portanto 1, 5, 3,.
Nós elevamos isso com o primeiro elemento do iqual é o número de caracteres (aqui dígitos) de a, ou seja 3, fornecendo um vetor 1, 125, 27que contém o qual nós sume o compara a.


A divisão inteira sempre arredonda para baixo? Caso contrário, você pode ter problemas com, por exemplo, 370 (um número narcísico) se transformando em 4,7,0 (que retornaria falso) ou 270 (não narcísico) se transformando em 3,7,0 (retornando verdadeiro).
Iszi

A divisão inteira não arredonda ... A divisão inteira de 370 por 100 é 3 com o restante de 70 e não 3,70.
plannapus

11
48 bytes ... alguém colocou isso na página inicial!
Giuseppe

9

Python 3, 56 bytes

Não muito ofuscado, mas uma solução simples.

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

11
O [e ]são desnecessários, e você pode soltar o espaço em frente fortambém, então:sum(int(c)**len(s)for c in s)
marinus

Fantástico! Obrigado pela dica.
Danmcardle

11
Você pode salvar dois caracteres removendo os espaços s = input()e outro movendo-o para 2,7, onde printnão é uma função.
Ben

Bom ponto, editado.
Danmcardle 17/11/2013

Eu acho que você deve salientar que adicionar chaves print(daí um caractere a mais) tornaria essa uma solução válida para Python 2.xe Python 3.x.
Martin Thoma

8

PHP, 80 74 66 caracteres

Solução PHP muito simples:

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

Ele assume error_reportingque não inclui avisos, caso contrário, serão necessários alguns caracteres extras para inicializar $s=0;e $i=0.

Thx @manatwork para encurtar muitos caracteres.


Não atribua $ a e $ l em instruções separadas. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;é mais curto.
manatwork

Como você já possui uma instrução que gera um aviso, basta adicionar outra: remova a inicialização da variável de controle de loop. Incrementar a variável de controle de loop também não precisa ser uma instrução independente. E as chaves definitivamente não são necessários: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
manatwork

@manatwork: Obrigada pela recepção calorosa para codegolf :)
Vlad Preda

Pode ser jogado para issofor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Jörg Hülsermann 17/05

8

Dc: 48 caracteres

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

Exemplo de execução:

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

Nunca realmente utilizados dc, salvo erros tipográficos frenéticos em tentativa de escrevercd
Stan Strum

8

K, 24 23

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

1 char raspado com reordenação

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

8

R, 53 bytes

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

O gsubregex insere espaços entre os caracteres, para que a scanfunção possa ler o número em um vetor de dígitos.


+1 eu nunca pensei em fazer isso, é brilhante.
plannapus


6

Powershell, 75 63 62 60 58

Edit: Atualizado de acordo com o comentário de @ Iszi (nota: isso conta para $xnão existir)

Edit: Adicionado as alterações de @ Danko.

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

58 56 caracteres

Se a entrada for limitada a 10 dígitos (inclui todos os int32)

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

Fiquei me perguntando se alguém faria o PowerShell antes de mim.
Iszi

Salve 12 caracteres adicionando outra variável $xe usando +=a soma em vez de measure -sumtestar $x-eq$n.
Iszi

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

11
@ DankoDurbić, Nice! A coerção de tipos geralmente é útil no golfe com código PoSh. Eu só recebem 62 embora quando eu corro'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant

11
@Rynant Bom ponto. Fiz sua verificação de comprimento no PowerShell e criei 62 também. Ao executar uma verificação de comprimento de forma semelhante ao script real , é exibida 61. Isso provavelmente se deve ao modo como o PowerShell lida com o ''que você substituiu ''. Levei o script original para o Excel para verificar novamente =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")e consegui 62 também. Claro, sempre poderíamos contar manualmente - mas quem realmente faz isso?
Iszi

5

Python 2.x - 51

Mesmo conceito da solução do crazedgremlin para o 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);}

Com recuo:

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
Você não precisa definir intpara variáveis ​​globais.
precisa saber é o seguinte

Woah. Você está lendo a entrada argc.
SIGSTACKFAULT

Além disso, o -lmtempo de compilação não deveria ter que contar com +1 byte?
SIGSTACKFAULT

@ Blacksilver o -lmsinalizador não é necessário para os compiladores C89.
Josh Josh

Aha. Aprenda uma coisa nova todos os dias.
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.

Com recuo

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 caracteres

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

11
Você não deve postar o número de ms para executar o código, mas o número de caracteres que você usou. ;)
usuário desconhecido

3

Awk: 40 39 caracteres

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

Exemplo de execução:

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


11
Você está usando a variável p em um único local, portanto, não é necessário. Você pode mover a inicialização de variável de um para o forpoupar a sua separado ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
manatwork

11
Ao mover a avaliação para a formais um personagem pode ser encurtado: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
manatwork

Oh, curioso! Eu tentei algo assim, mas não funcionou. Curioso o que deu errado.
usuário desconhecido

3

Lua (101 caracteres)

Lua não é conhecida por ser concisa, mas foi divertido tentar de qualquer maneira.

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

Melhorias são bem-vindas.


Como não é necessário que seu programa possa manipular e processar uma lista de números, eu não usaria bytes para implementar essa funcionalidade. Substituir o loop for n in io.lines()do [...]endpor n=io.read()salva alguns 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:

Se você estiver testando isso no seu console de desenvolvimento no Stack Exchange, esteja ciente de que há várias propriedades não padrão adicionadas String.prototypeque quebrarão essa solução, como String.prototype.formatUnicorn. Certifique-se de testar em um ambiente limpo, como ligado about:blank.


Eu conto 70 caracteres lá.
manatwork

@manatwork, whoops, esqueceu de contar a nova linha.
zzzzBov

Grande truque que decrementação!
manatwork

2
ele sempre retorna truepara mim, independentemente de entrada
koko

@koko, adicionei uma nota para explicar por que você está recebendo resultados incorretos.
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);};

Versão não 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);}

Chamado assim:

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

Devoluções:

true
true
false
false

Você pode remover os parênteses em torno dos argumentos lambda, a,l->funciona exatamente da mesma maneira.
FlipTack 6/01

Eu sei que você responder a esta há quase um ano, mas você pode golfe dois bytes: (a,l)->pode ser a->l->e bytepode 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

Japonês , 14 9 7 bytes

¶ì_xpZÊ

Experimente online


Explicação

Entrada implícita de número inteiro U.

ì_

Converta Upara uma matriz de dígitos ( ì), passe-a por uma função e converta novamente para um número inteiro depois.

xpZÊ

Reduza por adição ( x), elevando cada elemento à potência ( p) do comprimento ( Ê) da matriz no processo.

Verifique se o resultado é estritamente igual a U.


Eu acho ¥U¬®n pUlÃxque funcionaria para 11 bytes;) #
234 Oliver 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 comum - 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))))

Formatado:

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

Na área de trabalho, envie value:com o número e imprima.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.