Testez un nombre pour le narcissisme

53

Un nombre narcissique est un nombre qui est la somme de ses propres chiffres, chacun élevé à la puissance du nombre de chiffres.

Par exemple, prenons 153 (3 chiffres):

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

1634:

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

Le défi:

Votre code doit recevoir une entrée de l'utilisateur et générer une valeur True ou False selon que le nombre donné est un nombre narcissique.

La vérification d'erreur pour les chaînes de texte ou d'autres entrées non valides n'est pas requise. 1 ou 0 pour la sortie est acceptable. Le code qui génère simplement une liste de nombres narcissiques ou vérifie la saisie de l'utilisateur par rapport à une liste n'est pas admissible.

OEIS A005188

Iszi
la source
3
Est-ce que je peux sortir Truesi c'est un nombre, mais rien d'autre (dans ce cas, le nombre lui-même) sinon?
devRicher

Réponses:

39

APL (15)

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

Sorties 1si vrai et 0si faux.

Explication:

  • ∆←⍞: lire une ligne (en tant que caractères), stocker dans
  • (⍎¨∆)*⍴∆: évalue chaque personnage et élève-le au pouvoir⍴∆
  • ∆≡⍕+/: voir si l'entrée est égale à la représentation sous forme de chaîne de la somme de ceux-ci
marinus
la source
9
qu'est-ce que je viens de lire
Jbwilliams1
4
@LagWagon Le langage de Dieu
tomsmeding
21

GolfScript, 16 caractères

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

L'entrée doit être donnée sur STDIN, la sortie est 0 ou 1, indiquant un nombre non narcissique / narcissique.

Explication du code:

~              # 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
la source
J'ai fait une double-prise sur «~.», Mais il semble impossible de s'améliorer. Joli.
Peter Taylor
15

Mathematica, 43 caractères

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]
Alephalpha
la source
14

Perl, 38 caractères

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

Une implémentation assez simple.

Voici une version légèrement différente qui contient 35 caractères:

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

Cette version génère une valeur false si l'entrée est narcissique, sinon elle génère une valeur true (acceptée par Perl). On pourrait soutenir que cette version inversée est dans les limites de la description du défi, mais après réflexion, j'ai décidé de ne pas le faire. Je ne suis pas désespéré pour améliorer mon score. Encore.

boite à pain
la source
"La vérification d'erreur pour les chaînes de texte ou d'autres entrées non valides n'est pas requise." - Alors, pourquoi ne pas supposer que l'entrée sera un nombre valide, sans fin de nouvelle ligne? echo -n 153 | perl -pe '…'travaillera sans -l.
Manatwork
Je pense que tant que vous définissez ce que sont vos résultats vrais et faux, cela devrait être légal
Cruncher
Strictement parlant, le libellé du texte du défi laisse un peu d'ambiguïté quant à ce que Vrai / Faux ou 0/1 devrait signifier, alors je vais laisser passer celui-ci. Un script différent de longueur égale qui renvoie true pour les valeurs narcissiques aurait toutefois l'avantage.
Iszi
Même idée mais plus courte:perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s'
msh210 le
13

J, 23 caractères

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

(1!:1)1 est une entrée au clavier (retourne une chaîne).

".convertit l'entrée en un nombre; "0spécifie un rang (dimension) de 0, autrement dit, prend chaque caractère et le convertit en nombre.

^est la fonction de puissance et #est la fonction de longueur, prenant ainsi chaque chiffre à la puissance de la longueur de la chaîne (équivalent, le nombre de chiffres).

+/est juste somme, et =compare la somme et le nombre.

rationalis
la source
2
"Votre code doit recevoir une entrée de l'utilisateur et générer une valeur True ou False, selon que le nombre indiqué est un nombre narcissique." (c'est moi qui souligne)
John Dvorak
@JanDvorak My bad - ajout du clavier.
rationalis
12

Rubis, 34 + 5 = 39

Avec des indicateurs de ligne de commande

ruby -nlaF|

Courir

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

Affiche vrai ou faux.

histocrate
la source
3
C’est peut-être le drapeau le plus rubis que j’ai jamais vu dans un golf de code légitime: P
Porte-porte
11

R, 71 69 66 56 48

Réduit de 8 octets grâce à @Giuseppe ! L'idée était d'effectuer la division entière avant l'opération modulo.

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

Version (3 ans) avec explication correspondante:

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

a<-scan()prend un nombre (entier, réel, ...) en entrée (par exemple 153pour l'exemple).
idevient un vecteur contenant 3 à 1 (le nombre de caractères aétant 3).
%%est vectorisé donc a%%10^isignifie amodulo 1000, 100 et 10: il donne donc 153, 53, 3.
(a%%10^i)%/%10^(i-1)est la division entière de ce vecteur par 100, 10, 1: donc 1, 5, 3.
Nous élevons cela avec le premier élément iqui est le nombre de caractères (ici des chiffres) de a, c'est 3-à- dire , donnant ainsi un vecteur contenant ce 1, 125, 27que nous sumet auquel nous nous comparons a.

planificateur
la source
La division entière est-elle toujours arrondie vers le bas? Sinon, vous pourriez rencontrer des problèmes, par exemple 370 (un nombre narcissique) devenant 4,7,0 (ce qui rendrait faux) ou 270 (non narcissique) se transformant en 3,7,0 (devenant vrai).
Iszi
La division entière ne arrondit pas ... La division entière de 370 par 100 est de 3 avec le reste de 70 et non de 3,70.
Plannapus
1
48 octets ... quelqu'un est tombé sur la page d'accueil!
Giuseppe
9

Python 3, 56 octets

Pas très obscur, mais une solution simple.

s = input()
print(int(s)==sum(int(c)**len(s)for c in s))
danmcardle
la source
1
Les [et ]sont inutiles, et vous pouvez aussi laisser tomber l'espace devant for, alors:sum(int(c)**len(s)for c in s)
marinus
C'est génial! Merci pour le conseil.
danmcardle
1
Vous pouvez enregistrer deux caractères en supprimant les espaces s = input()et un autre en déplaçant ce paramètre vers 2.7 où il printne s'agit pas d'une fonction.
Ben
Bon point, édité.
danmcardle
Je pense que vous devriez souligner que l'ajout d'accolades à print(donc un caractère de plus) en ferait une solution valide Python 2.x et Python 3.x.
Martin Thoma
8

PHP, 80 74 66 caractères

Solution PHP très simple:

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

Il suppose error_reportingque les notifications ne sont pas incluses, sinon quelques caractères supplémentaires seront nécessaires pour initialiser $s=0;et $i=0.

Thx @manatwork pour raccourcir beaucoup de caractères.

Vlad Preda
la source
Ne pas assigner $ a et $ l dans des déclarations séparées. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a;est plus courte.
Manatwork
Comme vous avez déjà une instruction qui génère un avis, ajoutez-en une autre: supprimez l'initialisation de la variable de contrôle de boucle. L'incrémentation de la variable de contrôle de boucle n'a pas non plus besoin d'être une instruction autonome. Et les accolades ne sont certainement pas nécessaires: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;.
Manatwork
@manatwork: Merci pour l'accueil chaleureux réservé à codegolf :)
Vlad Preda
Peut être joué au golf à celafor(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a;
Jörg Hülsermann
8

Dc: 48 caractères

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

Échantillon échantillon:

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
homme au travail
la source
Jamais réellement utilisé dc, sauf pour les fautes de frappe effrayantes dans une tentative d'écriturecd
Stan Strum
8

K, 24 23

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

Rasé 1 personnage avec réorganisation

{x=+/{x xexp#x}"I"$'$x}
tmartin
la source
8

R, 53 octets

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

La gsubregex insère des espaces entre les caractères, de sorte que la scanfonction puisse lire le nombre dans un vecteur de chiffres.

flodel
la source
+1 je n'aurais jamais pensé à faire ça, c'est génial.
Plannapus
6

Kona, 18 ans

...

{x=+/(0$'u)^#u:$x}
tmartin
la source
6

Powershell, 75 63 62 60 58

Edit: mis à jour par le commentaire de @ Iszi (note: cela ne vaut pas pour $xnon existant)

Edit: Ajout des modifications de @ Danko.

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

58 56 caractères

Si l'entrée est limitée à 10 chiffres (inclut tous les int32)

($x=$n=read-host)[0..9]|%{$x-="$_*"*$n.length+1|iex};!$x
Rynant
la source
Je me demandais si quelqu'un allait faire PowerShell avant moi.
Iszi
Sauvegardez 12 caractères en ajoutant une autre variable $xet en utilisant +=pour faire votre somme au lieu de measure -sumpuis testez $x-eq$n.
Iszi
1
61 caractères:($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x
Danko Durbić
1
@ DankoDurbić, Nice! La coercition de type est souvent utile avec le golf au code PoSh. Je n'ai que 62 ans quand je cours'($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length
Rynant
1
@Rynant Bon point. J'ai examiné votre longueur dans PowerShell et en ai aussi proposé 62. Lorsque vous exécutez une vérification de longueur de la même manière par rapport au script réel , elle apparaît 61. Cela est probablement dû à la manière dont PowerShell traite les éléments ''que vous avez remplacés ''. J'ai pris le script original dans Excel pour vérifier avec =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x")et obtenu 62 également. Bien sûr, nous pourrions toujours le compter manuellement - mais qui fait vraiment cela?
Iszi
5

Python 2.x - 51

Même concept que la solution de crazedgremlin pour Python 3.x:

s=input();print s==sum(int(c)**len(`s`)for c in`s`)
utilisateur1354557
la source
4

C - 97 93 caractères

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

Avec indentation:

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
la source
2
Vous n'avez pas à définir intpour les variables globales.
Konrad Borowski
Woah. Vous lisez l'entrée dans argc.
SIGSTACKFAULT
Aussi, ne devriez-vous pas avoir à faire -lmà la compilation compter +1 octet?
SIGSTACKFAULT
@Blacksilver le -lmdrapeau n'est pas requis pour les compilateurs C89.
Josh
Aha. Apprenez une nouvelle chose chaque jour.
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.

Avec retrait

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
la source
4

05AB1E , 7 octets (non concurrents)

DSDgmOQ

Essayez-le en ligne!

-2 octets grâce à @daHugLenny

Urne Magique De Pieuvre
la source
3
Vous pouvez remplacer §1ôparS
acrolithe
3

Haskell 2010 - 76 caractères

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x
Nathan Baum
la source
1
Vous ne devriez pas publier le nombre de ms pour exécuter le code, mais le nombre de caractères que vous avez utilisés. ;)
utilisateur inconnu
3

Awk: 40 39 caractères

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

Échantillon échantillon:

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
homme au travail
la source
3

Bash, 64 caractères

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

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

Utilisateur inconnu
la source
1
Vous utilisez la variable p dans un seul endroit, donc inutile de l’utiliser. Vous pouvez déplacer l'initialisation d'une variable dans l' forépargner son séparée ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1].
Manatwork
1
En déplaçant l'évaluation dans le forun ou plusieurs caractères peut être raccourci: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1].
Manatwork
Oh, curieux! J'ai essayé quelque chose comme ça, mais ça n'a pas marché. Curieux de savoir ce qui s'est mal passé.
Utilisateur inconnu
3

Lua (101 caractères)

Lua n'est pas réputée pour sa concision, mais c'était amusant d'essayer quand même.

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

Les améliorations sont les bienvenues.

Criptych se dresse avec Monica
la source
Comme il n'est pas nécessaire que votre programme puisse gérer et traiter une liste de nombres, je ne voudrais pas utiliser d'octets pour implémenter cette fonctionnalité. Remplacer la boucle for n in io.lines()do [...]endpar n=io.read()enregistre quelques octets ( TIO ).
Jonathan Frech
3

JavaScript - 70 58 caractères

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

Remarque:

Si vous testez cela dans votre console de développement sur Stack Exchange, sachez qu'un certain nombre de propriétés non standard ajoutées à String.prototypecela vont casser cette solution, telles que String.prototype.formatUnicorn. Assurez-vous de tester dans un environnement propre, tel que sur about:blank.

zzzzBov
la source
J'y compte 70 personnages.
manatwork
@manatwork, whoops, a oublié de compter la nouvelle ligne.
ZzzzBov
Bon tour que la décrémentation!
Manatwork
2
ça revient toujours truepour moi, peu importe l'entrée
koko
@koko, j'ai ajouté une note pour expliquer pourquoi vous recevez des résultats incorrects.
zzzzBov
3

Java - 84 octets

(a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

Version non lambda: 101 octets:

boolean n(String a,int l){int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}

Appelé comme ça:

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

Résultats:

true
true
false
false
Hypino
la source
Vous pouvez supprimer les parenthèses autour des arguments lambda, a,l->fonctionne exactement de la même manière.
FlipTack
Je sais que vous avez répondu à cette question il y a presque un an, mais vous (a,l)->pouvez jouer au golf deux octets: peut être a->l->et bytepeut être int:a->l->{int s=0;for(int c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}
Kevin Cruijssen le
3

Japt , 14 9 7 octets

¶ì_xpZÊ

Essayez-le en ligne


Explication

Entrée implicite d'entier U.

ì_

Convertissez-le Uen tableau de digits ( ì), transmettez-le à travers une fonction et reconvertissez-le en entier après.

xpZÊ

Réduire par addition ( x), en élevant chaque élément à la puissance ( p) de la longueur ( Ê) du tableau dans le processus.

Vérifiez si le résultat est strictement égal à U.

Hirsute
la source
Je pense ¥U¬®n pUlÃxque fonctionnerait pour 11 octets;)
Oliver
2

F # - 92 caractères

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

Common Lisp - 116 102 caractères

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

Formaté:

(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
la source
2

Smalltalk - 102 99 caractères

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

Dans l'espace de travail, envoyez value:avec le numéro et imprimez-le.

Paul Richter
la source
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;}}
Ce n'est pas AL.
la source
2

Haskell, 68 66 octets

d 0=[]
d n=mod n 10:d(div n 10)
sum.(\a->map(^length a)a).d>>=(==)

Usage:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
Angs
la source