Finden Sie heraus, ob eine Nummer glücklich ist oder nicht?


21

Eine Glückszahl wird durch den folgenden Prozess definiert. Beginnen Sie mit einer positiven ganzen Zahl, ersetzen Sie die Zahl durch die Summe der Quadrate ihrer Ziffern und wiederholen Sie den Vorgang, bis die Zahl gleich 1 ist (wo sie verbleibt), oder sie wiederholt sich endlos in einem Zyklus, der nicht 1 enthält. Diese Zahlen für die dieser Prozess mit 1 endet, sind glückliche Zahlen, während diejenigen, die nicht mit 1 enden, unglückliche Zahlen (oder traurige Zahlen) sind. Gegeben, eine Zahl drucken, ob es glücklich oder unglücklich ist.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

Hinweis: Ihr Programm sollte für Zahlen unter 1.000.000.000 nicht länger als 10 Sekunden dauern.

Antworten:



11

Ruby, 77 Zeichen

a=gets.to_i;a=eval"#{a}".gsub /./,'+\&**2'until a<5
puts a<2?:Happy: :Unhappy

Ok, ich verstehe ein bisschen, wie das funktioniert (buchstäblich jede Zahl nehmen, sie teilen und das Quadrat jeder Ziffer hinzufügen), aber was ist mit der Stoppbedingung (a <5) und der Verwendung von (a <2), um zu entscheiden, ob es glücklich ist oder nicht? Ich stelle die Gültigkeit nicht in Frage, nur die Logik.
Mr. Llama

2
Das ist dasselbe wie a <= 4und a <= 1. Wenn der Zyklus eine 1 enthält, ist er glücklich, und wenn er eine 4 enthält, ist er nicht glücklich. Siehe den Wikipedia-Abschnitt über den unglücklichen Zyklus. Sobald der Wert a4 oder weniger ist, prüft er, ob a ist - das Ergebnis ist Ihre Antwort.
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");}

Dies verwendet ein 2 30- Byte-Array (1 GB) als Bitmap, um zu verfolgen, welche Zahlen im Zyklus aufgetreten sind. Unter Linux funktioniert dies tatsächlich und effizient, vorausgesetzt, die Speicherüberlastung ist aktiviert (was normalerweise die Standardeinstellung ist). Bei einem Overcommitting werden Seiten des Arrays bei Bedarf zugewiesen und auf Null gesetzt.

Beachten Sie, dass beim Kompilieren dieses Programms unter Linux ein Gigabyte RAM benötigt wird.


1
Warum benötigen Sie für dieses Problem ungefähr so ​​viel Speicher?
Peter Olson

1
@Peter: Ich nehme an, der Ansatz ist, (naiv) einen Zyklus für eine beliebige Zahl im zulässigen Eingabebereich von 1 bis 1.000.000.000 abzufangen. Aber ich stimme zu, dass im Lichte der Happy-Number-Theorie nur überprüft werden muss, ob die Zahl 4 erreicht ist, da dies der einzige Zyklus ist, der jemals auftreten wird.
Mellamokb

Ich bin gespannt: Warum erfordert das Kompilieren so viel RAM?
Peter Taylor

1
Scheint unter Windows 7 mit MSVC 10 einwandfrei zu funktionieren. Verbraucht beim Kompilieren keine nennenswerte Menge an Speicher und markiert nur das Array in der Auslagerungsdatei (etwas, das sich sicherer anhört als die Geschichte, die Sie über die Überbelegung von Speicher verbunden haben ;-)) .
Joey

1
Ich liebe die Naivität dieses Ansatzes. Und der Missbrauch von for-Schleifen ist wunderschön.
DMCKEE

6

Haskell - 77

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

6

Golfscript, 49 43 41 40 39 Zeichen

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

Jede glückliche Zahl konvergiert zu 1; Jede unglückliche Zahl konvergiert zu einem Zyklus, der 4 enthält. Abgesehen davon, dass diese Tatsache ausgenutzt wird, wird hier kaum Golf gespielt.

(Dank an Ventero, von dessen Ruby-Lösung ich einen Trick geklaut und 6 Zeichen gespart habe).


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

Genannt als etex filename.tex 34*23 + 32/2 ?(einschließlich des Fragezeichens am Ende). Leerzeichen im Ausdruck spielen keine Rolle.

EDIT: Ich bin auf 123 gekommen , aber jetzt ist die Ausgabe dvi (wenn kompiliert mit etex) oder pdf (wenn kompiliert mit pdfetex). Da TeX eine Schriftsprache ist, halte ich das für fair.

\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

4

Python - 81 Zeichen

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

Inspiration von Ventero und Peter Taylor.


2
besser dran int(c)als 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')

Die Eingabe erfolgt durch Setzen von a auf die gewünschte Zahl.

Dank an mellamokb.


1 n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
Zeichen

@ Mella Danke. Ich habe auch einen anderen Saibling rasiert, indem ich zu gewechselt ||habe |.
Peter Olson

8 Zeichen sparen: Entfernen n==4?h.... Ändern, um ... while-Schleife mit Bedingung auszuführen while(n>4). Verwenden Sie stattdessen diese abschließende Aussage:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb

@ Mella Clever, ich mag es.
Peter Olson

@ Mella n muss vor der while-Schleife definiert werden, ich versuche zu überlegen, wie man nicht wiederholtn=0;
Peter Olson

4

Python (98, aber zu durcheinander, um es nicht zu teilen)

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

Viel zu lange, um wettbewerbsfähig zu sein, aber vielleicht gut zum Lachen. In Python wird "faul" ausgewertet. Wirklich ziemlich ähnlich dem Haskell-Eintrag, jetzt, wo ich darüber nachdenke, nur ohne den Charme.


4

DC - 47 Zeichen

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

Kurze Beschreibung:

I~: Ermitteln Sie den Quotienten und den Rest bei der Division durch 10
d*.: Quadrieren Sie den Rest.
0<H: Wenn der Quotient größer als 0 ist, rekursiv wiederholen.
+: Summiere die Werte beim Verkleinern des rekursiven Stapels.

4<h: Wiederholen Sie das Quadratsummenbit, während der Wert größer als 4 ist.


4

Befunge, 109

Gibt korrekte Werte für 1 <= n <= 10 9 -1 zurück.

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

3

J, 56

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

Ein Verb und kein eigenständiges Skript, da die Frage nicht eindeutig ist.

Verwendung:

   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  

3

Scala, 145 Zeichen

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

1
Wäre nicht (n*n)kürzer als n*n , oder reicht Leerzeichen nicht aus, um einen if-Ausdruck vom zu trennen else?
Peter Taylor

Ja, das habe ich getan, Peter.
Benutzer unbekannt

Hier ist eine 126-Byte-Schwanz-rekursive Version ohne Mustererkennung: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: Warum postest du es nicht als neue Antwort?
Benutzer unbekannt

Der ursprüngliche Beitrag ist alt; Ich habe nur versucht, Ihre Lösung zu verbessern.
6infinity8

3

J (50)

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

Ich bin sicher ein kompetenterer J-er, als ich das noch kürzer machen kann. Ich bin ein relativer Neuling.

Neu und verbessert:

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

Neu und noch besser dank ʇǝɥʇıɐɔuʇǝɥʇs:

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

1
Sie können einen Charakter erhalten, indem Sie "appy" nicht aufteilen. Ich denke, Sie können auch die Klammern um d ("." 0) entfernen - Adverbien binden enger als Konjunktionen.
Jesse Millikan

Ich kann die Klammern nicht entfernen ("."0). Das führt zu einem Rangfehler, aber wenn ich nicht 'Happy' teile und das Ergebnis in der Box lasse, kann ich einen Charakter speichern.
Gregory Higley

Der Grund, warum ich die Klammern nicht auslassen kann, ("."0)ist, dass Konjunktionen für die gesamte vorhergehende Reihe von Verben gelten, an die sie angehängt sind, was ich nicht möchte. Wenn ich sage +/@:("."0)@":, ist das ganz anders als das +/@:"."0@:, was eigentlich ist (+/@:".)"0@:.
Gregory Higley

1
Eine massive necro, aber man konnte 4 Zeichen sparen durch Ersetzen 'Unhappy';'Happy'mit Unhappy`Happy.
15.

@ ɐɔıɐɔuʇǝɥʇs Das funktioniert, aber wo ist dokumentiert, dass Sie das Zitieren von Strings mit `überspringen können?
Gregory Higley

2

Python (91 Zeichen)

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

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

Besser lesbar:

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

Wäre kürzer, wenn Sie einfach "Happy" oder "Unhappy" aus dem zurückgeben würden (do), aber das würde wohl nicht als ganzes Programm gelten



2

Gelee , 17 Bytes (nicht konkurrierend *)

* Herausforderung nach den Terminen

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

Probieren Sie es online!

Wie?

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

1

Perl 5 - 77 Bytes

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

$ n ist der Eingabewert


1

05AB1E , 21 Bytes

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

Probieren Sie es online aus oder überprüfen Sie die ersten 100 Testfälle .

Erläuterung:

Jede Zahl wird irgendwann entweder 1oder ergeben 4, so dass wir eine Endlosschleife ausführen und anhalten, sobald die Zahl unter 5 liegt.

'ŽØ                    '# 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)

Sehen Sie diese 05AB1E Spitze von mir (Abschnitt Wie das Wörterbuch benutzen? ) Zu verstehen , warum 'ŽØist "happy".


0

C ++ 135, 2 Zeilen

#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";}

Dies ist eine modifizierte Version von der, die ich hier gemacht habe:

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


Was ist das zu &999tun? Und wie funktioniert es, wenn jein Müllwert ist?
David sagt Reinstate Monica

@ Dgrin91, ich habe das vor 3 Jahren geschrieben, daher kann ich mich nicht genau erinnern, wie es funktioniert. Ich denke, das & 999 macht die Aussage if(j==999){n = 0;}else{n=n*n +i;}, j sollte kein Müllwert sein, Globals werden mit Null initialisiert.
Scott Logan

0

Ja, diese Herausforderung hat drei Jahre; Ja, es gibt bereits eine Gewinnerantwort. aber da ich gelangweilt war und dies für eine andere Herausforderung tat, dachte ich, ich könnte es hier aufstellen. Überraschung Überraschung, es ist lang - und in ...

Java - 280 264 Bytes

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

Ungolfed:

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


0

Clojure, 107 97 Bytes

Update: Unnötig entfernt let Bindung entfernt.

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

Zum ersten Mal mit einem verschachtelten for: o


0

R 117 91 Bytes

-16 Bytes dank Giuseppe

a=scan();while(!a%in%c(1,4))a=sum((a%/%10^(0:nchar(a))%%10)^2);`if`(a-1,'unhappy','happy')

1
Verwenden Sie strtoianstelle von as.numericund pasteanstelle von as.character, aber es gibt einen kürzeren Ansatz, um die Ziffern zu erhalten . Wenn Sie `if`(a-1,"unhappy","happy")stattdessen verwenden, sollte das ein anderes Byte speichern. Schließlich können Sie dies anonymisieren, um ein paar weitere Bytes zu entfernen.
Giuseppe



-1

C: 1092 Zeichen

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

6
Willkommen bei Programming Puzzles & Code Golf, @jannat. Bitte beachten Sie, dass Codegolf eine Herausforderung ist, den kürzestmöglichen Code zu schreiben. Das bedeutet, dass wir hier nicht eingerückten und fast nicht lesbaren Code schreiben und die Grenzen der Sprachsyntax erzwingen, um unsere Codes so kurz wie möglich zu halten.
Manatwork

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.