Trouvez si un nombre est heureux ou non?

21

Un nombre heureux est défini par le processus suivant. En commençant par n'importe quel entier positif, remplacez le nombre par la somme des carrés de ses chiffres et répétez le processus jusqu'à ce que le nombre soit égal à 1 (où il restera), ou il boucle sans fin dans un cycle qui ne comprend pas 1. Ces nombres pour lesquels ce processus se termine par 1 sont des nombres heureux, tandis que ceux qui ne se terminent pas par 1 sont des nombres malheureux (ou des nombres tristes). Étant donné un numéro, indiquez s'il est heureux ou non.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

Remarque: Votre programme ne devrait pas prendre plus de 10 secondes pour tout nombre inférieur à 1 000 000 000.

fR0DDY
la source

Réponses:

8

Golfscript - 34 caractères

~{0\`{48-.*+}/}9*1="UnhH"3/="appy"

Fondamentalement les mêmes que ceux- ci et ceux - ci .

La raison de 9 itérations est décrite dans ces commentaires (cela renvoie théoriquement des valeurs correctes jusqu'à environ 10^10^10^974( A001273 )).

Nabb
la source
11

Ruby, 77 caractères

a=gets.to_i;a=eval"#{a}".gsub /./,'+\&**2'until a<5
puts a<2?:Happy: :Unhappy
Ventero
la source
Ok, donc je comprends un peu comment cela fonctionne (en prenant littéralement chaque nombre, en le divisant et en ajoutant le carré de chaque chiffre), mais quelle est la condition d'arrêt de (a <5) et utilise (a <2) pour décider si elle est heureuse ou pas? Je ne remets pas en question la validité, juste la logique.
M. Llama
2
C'est la même chose que a <= 4et a <= 1. Si le cycle a un 1, alors il est heureux, et s'il a un 4, alors il n'est pas heureux. Voir la section wikipedia sur le cycle malheureux. Donc, une fois la valeur de a4 ou moins, il vérifie si a est - le résultat est votre réponse.
Casey
8

C - 115

char b[1<<30];a;main(n){for(scanf("%d",&n);b[n]^=1;n=a)for
(a=0;a+=n%10*(n%10),n/=10;);puts(n-1?"Unhappy":"Happy");}

Cela utilise un 2 tableau de 30 octets (1 Go) comme bitmap pour garder une trace des numéros rencontrés au cours du cycle. Sous Linux, cela fonctionne réellement et efficacement, à condition que la surcharge de mémoire soit activée (ce qui est généralement le cas par défaut). En cas de surcharge, les pages du tableau sont allouées et remises à zéro à la demande.

Notez que la compilation de ce programme sous Linux utilise un gigaoctet de RAM.

Joey Adams
la source
1
Pourquoi auriez-vous besoin d'un endroit proche de cette quantité de mémoire pour ce problème?
Peter Olson
1
@Peter: Je suppose que l'approche consiste à (naïvement) attraper un cycle pour n'importe quel nombre dans la plage d'entrée autorisée de 1 à 1 000 000 000. Mais je conviens qu'à la lumière de la théorie des nombres heureux, la seule vérification nécessaire est de savoir si le nombre 4 est atteint, car c'est le seul cycle qui se produira jamais.
mellamokb
Je suis curieux: pourquoi sa compilation nécessite-t-elle autant de RAM?
Peter Taylor
1
Semble fonctionner correctement sur Windows 7 avec MSVC 10. Ne consomme pas de quantité notable de mémoire lors de la compilation et ne marque que le tableau dans le fichier d'échange (quelque chose qui semble beaucoup plus sûr que l'histoire que vous avez liée à propos de la surcharge mémoire suggère ;-)) .
Joey
1
J'adore la naïveté de cette approche. Et l'abus des boucles for est magnifique.
dmckee
6

Haskell - 77

f 1="Happy"
f 4="Unhappy"
f n=f$sum[read[c]^2|c<-show n]
main=interact$f.read
Joey Adams
la source
6

Golfscript, 49 43 41 40 39 caractères

~{0\10base{.*+}/.4>}do(!"UnhH"3/="appy"

Chaque nombre heureux converge vers 1; chaque nombre malheureux converge vers un cycle contenant 4. En plus d'exploiter ce fait, c'est à peine joué au golf.

(Merci à Ventero, de la solution Ruby dont j'ai réussi une astuce et enregistré 6 caractères).

Peter Taylor
la source
5

eTeX, 153

\let~\def~\E#1{\else{\fi\if1#1H\else Unh\fi appy}\end}~\r#1?{\ifnum#1<5
\E#1\fi~\s#1{0?}}~\s#1{+#1*#1\s}~~{\expandafter\r\the\numexpr}\message{~\noexpand

Appelé comme etex filename.tex 34*23 + 32/2 ?(y compris le point d'interrogation à la fin). Les espaces dans l'expression n'ont pas d'importance.

EDIT: je suis descendu à 123 , mais maintenant la sortie est dvi (si compilée avec etex) ou pdf (si compilée avec pdfetex). Puisque TeX est un langage de composition, je suppose que c'est juste.

\def~{\expandafter\r\the\numexpr}\def\r#1?{\ifnum#1<5 \if1#1H\else
Unh\fi appy\end\fi~\s#1{0?}}\def\s#1{+#1*#1\s}~\noexpand
Bruno Le Floch
la source
4

Python - 81 caractères

n=input()
while n>4:n=sum((ord(c)-48)**2for c in`n`)
print("H","Unh")[n>1]+"appy"

Une inspiration inspirée de Ventero et Peter Taylor.

Juan
la source
2
mieux vaut faire un int(c)que ord(c)-48....
st0le
4

Javascript ( 94 92 87 86)

do{n=0;for(i in a){n+=a[i]*a[i]|0}a=n+''}while(n>4);alert(['H','Unh'][n>1?1:0]+'appy')

L'entrée est fournie en réglant a sur le nombre souhaité.

Crédits à mellamokb.

Peter Olson
la source
Enregistrer 1 personnage:n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
mellamokb
@mella Merci. J'ai également rasé un autre personnage en changeant ||pour |.
Peter Olson
Enregistrer 8 caractères: supprimer n==4?h.... Changez pour faire ... tout en boucle avec condition while(n>4). Utilisez alors cette déclaration finale à la place:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb
@Mella Clever, j'aime ça.
Peter Olson
@Mella n doit être défini avant la boucle while, j'essaie de penser à ne pas répétern=0;
Peter Olson
4

Python (98, mais trop foiré pour ne pas partager)

f=lambda n:eval({1:'"H"',4:'"Unh"'}.get(n,'f(sum(int(x)**2for x in`n`))'))
print f(input())+"appy"

Bien trop long pour être compétitif, mais peut-être bon pour rire. Il fait une évaluation "paresseuse" en Python. Vraiment assez similaire à l'entrée Haskell maintenant que j'y pense, juste sans aucun charme.


la source
4

dc - 47 caractères

[Unh]?[[I~d*rd0<H+]dsHxd4<h]dshx72so1=oP[appy]p

Brève description:

I~: Obtenez le quotient et le reste lorsque vous divisez par 10
d*.: Mettez le reste au carré.
0<H: Si le quotient est supérieur à 0, répétez récursivement.
+: Somme les valeurs lors de la réduction de la pile récursive.

4<h: Répéter le bit de somme des carrés lorsque la valeur est supérieure à 4.

Nabb
la source
4

Befunge, 109

Renvoie des valeurs correctes pour 1 <= n <= 10 9 -1.

v v              <   @,,,,,"Happy"<      >"yppahnU",,,,,,,@
>&>:25*%:*\25*/:#^_$+++++++++:1-!#^_:4-!#^_10g11p
Lowjacker
la source
3

J, 56

'Happy'"_`('Unhappy'"_)`([:$:[:+/*:@:"."0@":)@.(1&<+4&<)

Un verbe plutôt qu'un script autonome car la question est ambiguë.

Usage:

   happy =: 'Happy'"_`('Unhappy'"_)`([:$:[:+/*:@:"."0@":)@.(1&<+4&<)
happy =: 'Happy'"_`('Unhappy'"_)`([:$:[:+/*:@:"."0@":)@.(1&<+4&<)
   happy"0 (7 4 13)
happy"0 (7 4 13)
Happy  
Unhappy
Happy  
Jesse Millikan
la source
3

Scala, 145 caractères

def d(n:Int):Int=if(n<10)n*n else d(n%10)+d(n/10)
def h(n:Int):Unit=n match{
case 1=>println("happy")
case 4=>println("unhappy")
case x=>h(d(x))}
Utilisateur inconnu
la source
1
Ne serait pas (n*n)plus court que n*n , ou les espaces ne suffisent-ils pas pour séparer une expression if du else?
Peter Taylor
Oui, je l'ai fait, Peter.
utilisateur inconnu
Voici une version récursive de queue de 126 octets, sans correspondance de modèle:def h(s: String):String=if(s=="1")"H"else if(s=="4")"Unh"else h(s.map(_.asDigit).map(a=>a*a).sum+"");print(h(readLine)+"appy")
6infinity8
@ 6infinity8: Pourquoi ne l'affichez-vous pas comme une nouvelle réponse?
utilisateur inconnu
Le poste initial est ancien; J'essayais juste d'améliorer votre solution.
6infinity8
3

J (50)

'appy',~>('Unh';'H'){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)

Je suis sûr qu'un J-er plus compétent que je ne peux le rendre encore plus court. Je suis relativement nouveau.

Nouveau et amélioré:

('Unhappy';'Happy'){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)

Plus récent et encore plus amélioré, grâce aux ɐɔıʇǝɥʇuʎs:

(Unhappy`Happy){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)
Gregory Higley
la source
1
Vous pouvez obtenir un personnage en ne séparant pas «appy». Je pense que vous pouvez également supprimer les parenthèses autour de d ("." 0) - les adverbes se lient plus étroitement que les conjonctions.
Jesse Millikan
Je ne peux pas supprimer les parenthèses autour ("."0). Cela produit une erreur de classement, mais si je ne divise pas «Heureux» et que je laisse le résultat dans une case, je peux enregistrer un personnage.
Gregory Higley
La raison pour laquelle je ne peux pas omettre les parenthèses ("."0)est que les conjonctions s'appliquent à l'ensemble du train de verbes précédent auquel elles sont attachées, ce qui n'est pas ce que je veux. Si je dis +/@:("."0)@":, c'est très différent de +/@:"."0@:ce qui est en fait (+/@:".)"0@:.
Gregory Higley
1
Un énorme nécro, mais vous pouvez économiser 4 caractères en les remplaçant 'Unhappy';'Happy'par Unhappy`Happy.
ɐɔı'uʎs
@ ɐɔıʇǝɥʇuʎs Cela fonctionne, mais où est-il documenté que vous pouvez sauter la citation des chaînes avec `?
Gregory Higley
2

Python (91 caractères)

a=lambda b:b-1and(b-4and a(sum(int(c)**2for c in`b`))or"Unh")or"H";print a(input())+"appy"
marinus
la source
2

Common Lisp 138

(format t"~Aappy~%"(do((i(read)(loop for c across(prin1-to-string i)sum(let((y(digit-char-p c)))(* y y)))))((< i 5)(if(= i 1)"H""Unh"))))

Plus lisible:

(format t "~Aappy~%"
        (do
          ((i (read)
              (loop for c across (prin1-to-string i)
                    sum (let
                          ((y (digit-char-p c)))
                          (* y y)))))
          ((< i 5) (if (= i 1) "H" "Unh"))))

Serait plus court pour renvoyer juste "Heureux" ou "Malheureux" directement depuis le (do), mais sans doute cela ne compterait pas comme un programme entier

daniero
la source
2

K, 43

{{$[4=d:+/a*a:"I"$'$x;unhappy;d]}/x;`happy}
tmartin
la source
2

Gelée , 17 octets (hors compétition *)

* Défi linguistique post-dates

D²SµÐLỊị“¢*X“<@Ḥ»

Essayez-le en ligne!

Comment?

D²SµÐLỊị“¢*X“<@Ḥ» - Main link: n
   µÐL            - loop while the accumulated unique set of results change:
D                 -   cast to a decimal list
 ²                -   square (vectorises)
  S               -   sum
                  - (yields the ultimate result, e.g. n=89 yields 58 since it enters the
                  -  "unhappy circle" at 145, loops around to 58 which would yield 145.)
      Ị           - insignificant? (abs(v)<=1 - in this case, 1 for 1, 0 otherwise)
        “¢*X“<@Ḥ» - dictionary lookup of ["Happy", "Unhappy"] (the central “ makes a list)
       ị          - index into
                  - implicit print
Jonathan Allan
la source
1

Perl 5-77 octets

{$n=$_*$_ for split//,$u{$n}=$n;exit warn$/.'un'[$n==1].'happy'if$u{$n};redo}

$ n est la valeur d'entrée

Kaundur
la source
1

05AB1E , 21 octets

'ŽØs[SnOD5‹#}≠i„unì}™

Essayez-le en ligne ou vérifiez les 100 premiers cas de test .

Explication:

Chaque nombre entraînera éventuellement l'un 1ou l' autre 4, nous bouclons donc indéfiniment et nous nous arrêtons dès que le nombre est inférieur à 5.

'ŽØ                    '# Push string "happy"
   s                    # Swap to take the (implicit) input
    [       }           # Loop indefinitely
     S                  #  Convert the integer to a list of digits
      n                 #  Square each
       O                #  Take the sum
        D5‹#            #  If this sum is smaller than 5: stop the infinite loop
             i    }    # If the result after the loop is NOT 1:
               unì     #  Prepend string "un" to string "happy"
                       # Convert the string to titlecase (and output implicitly)

Voir cette astuce de la mine de 05AB1E (section Comment utiliser le dictionnaire? ) Pour comprendre pourquoi 'ŽØest "happy".

Kevin Cruijssen
la source
0

C ++ 135, 2 lignes

#include<iostream>
int n,i,j;int main(){for(std::cin>>n;n>1;n=++j&999?n*n+i:0)for(i=0;n/10;n/=10)i+=n%10*(n%10);std::cout<<(n?"H":"Unh")<<"appy";}

Ceci est une version modifiée de celle que j'ai faite ici:

/programming/3543811/code-golf-happy-primes/3545056#3545056

Scott Logan
la source
Quel est le &999faire? Et comment ça marche si jc'est une valeur poubelle?
David dit Réintégrer Monica le
@ Dgrin91, je l'ai écrit il y a 3 ans, donc je ne me souviens pas exactement comment cela fonctionne. Je pense que le & 999 fait la déclaration if(j==999){n = 0;}else{n=n*n +i;}, j ne devrait pas être une valeur poubelle, les globaux sont initialisés à zéro.
Scott Logan
0

Oui, ce défi a trois ans; oui, il a déjà une réponse gagnante; mais comme je m'ennuyais et que je faisais cela pour un autre défi, j'ai pensé que je pourrais le mettre ici. Surprise surprise, c'est long - et en ...

Java - 280 264 octets

import java.util.*;class H{public static void main(String[]a){int n=Integer.parseInt(new Scanner(System.in).nextLine()),t;while((t=h(n))/10!=0)n=t;System.out.print(t==1?"":"");}static int h(int n){if(n/10==0)return n*n;else return(int)Math.pow(n%10,2)+h(n/10);}}

Non golfé:

import java.util.*;

class H {

    public static void main(String[] a) {
        int n = Integer.parseInt(new Scanner(System.in).nextLine()), t;
        while ((t = h(n)) / 10 != 0) {
            n = t;
        }
        System.out.print(t == 1 ? "" : "");
    }

    static int h(int n) {
        if (n / 10 == 0) {
            return n * n;
        } else {
            return (int) Math.pow(n % 10, 2) + h(n / 10);
        }
    }
}
Rodolfo Dias
la source
0

C # 94 octets

int d(int n)=>n<10?n*n:(d(n%10)+d(n/10));string h(int n)=>n==1?"happy":n==4?"unhappy":h(d(n));

Pour tout nombre donné (as int), h()renvoie la valeur correcte. Vous pouvez essayer le code sur .NetFiddle .

Félicitations à l' utilisateur inconnu pour l' algorithme d' origine .

aloisdg dit Réintégrer Monica
la source
0

Clojure, 107 97 octets

Mise à jour: suppression de la letliaison inutile .

#(loop[v %](case v 1"Happy"4"Unhappy"(recur(apply +(for[i(for[c(str v)](-(int c)48))](* i i))))))

Original:

#(loop[v %](let[r(apply +(for[i(for[c(str v)](-(int c)48))](* i i)))](case r 1"Happy"4"Unhappy"(recur r))))

Première utilisation d'un imbriqué for: o

NikoNyrh
la source
0

R, 117 91 octets

-16 octets grâce à Giuseppe

a=scan();while(!a%in%c(1,4))a=sum((a%/%10^(0:nchar(a))%%10)^2);`if`(a-1,'unhappy','happy')
Andrew Haynes
la source
1
Utilisez strtoiau lieu de as.numericet pasteau lieu de as.character, mais il existe une approche plus courte pour obtenir les chiffres . Si vous utilisez à la `if`(a-1,"unhappy","happy")place cela devrait enregistrer un autre octet. Enfin, vous pouvez le rendre anonyme pour raser quelques octets supplémentaires.
Giuseppe
-1

C: 1092 caractères

#include <iostream>
using namespace std ;
int main ()
{
    int m , a[25] , kan=0 , y , z=0  , n , o=0, s , k=0 , e[25]  ;
    do {
m :
        for ( int j=1 ; j <10000 ; j++ )
        {   
n:
            for (int i=0 ; j!=0 ; i++ )
            {
                a[i]=j%10 ;
                j/=10 ;
                kan++ ;
            }
            for ( int i=0 ; i<kan ; i++ )
            {
                y=a[i]*a[i] ;
                z+=y ;
            }
            k+=1 ;
            if (z==1)
            {
              cout<<j<<endl;
               o++ ;
            }

            else 
            {   
                 for (int f=0 ; f<k ; f++ )
                 {
                     e[f]=z ;
                 }
                 for ( int f=0 ; f=k-1 ; f++ )
                 {
                     for ( int p=f+1 ; p <k-1 ; p++ )
                     {
                         if(e[f]=e[p])
                             goto m ;
                         else { j=z ; goto n ; } 
                     }
                 }
            }
        }
    }while(o!=100) ;
    return 0 ;
}
jannat
la source
6
Bienvenue sur Programming Puzzles & Code Golf, @jannat. Veuillez noter que le golf de code est un défi d'écrire le code le plus court possible. Cela signifie, ici nous écrivons le code presque illisible et non indenté et forcer les limites de la syntaxe du langage pour raccourcir nos codes possible.
manatwork
xkcd.com/292
aditsu