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

Iszi
fonte
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
marinus
fonte
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)
Howard
fonte
Eu dei uma olhada dupla em `` ~. `` `Mas parece impossível melhorar. Agradável.
Peter Taylor
15

Mathematica, 43 caracteres

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]
alefalpha
fonte
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.

caixa de pão
fonte
“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.

racionalis
fonte
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.

histocrata
fonte
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.

plannapus
fonte
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))
danmcardle
fonte
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.

Vlad Preda
fonte
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
homem a trabalhar
fonte
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}
tmartin
fonte
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.

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

Kona, 18

...

{x=+/(0$'u)^#u:$x}
tmartin
fonte
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
Rynant
fonte
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`)
user1354557
fonte
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);
}
Josh
fonte
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.
Teun Pronk
fonte
4

05AB1E , 7 bytes (não concorrente)

DSDgmOQ

Experimente online!

-2 bytes graças a @daHugLenny

Urna de polvo mágico
fonte
3
Você pode substituir §1ôporS
acrolith 8/16
3

Haskell 2010 - 76 caracteres

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x
Nathan Baum
fonte
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
homem a trabalhar
fonte
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))

Usuário desconhecido
fonte
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.

criptych fica com Monica
fonte
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.

zzzzBov
fonte
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
Hypino
fonte
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.

Shaggy
fonte
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"
Smetad Anarkist
fonte
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)))
Paul Richter
fonte
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.

Paul Richter
fonte
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;}}
It'sNotALie.
fonte
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
Angs
fonte