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


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

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)

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

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.


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


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.


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.


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

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.


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

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}

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.


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


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

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

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

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.


3

Haskell 2010 - 76 caractères

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

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

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


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.


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.


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

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.


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"

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

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.


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 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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.