Sprawdź, czy numer jest szczęśliwy, czy nie?


21

Szczęśliwa liczba jest definiowana przez następujący proces. Zaczynając od dodatniej liczby całkowitej, zamień liczbę na sumę kwadratów jej cyfr i powtarzaj proces, aż liczba wyniesie 1 (gdzie pozostanie), lub zapętli się bez końca w cyklu, który nie obejmuje 1. Te liczby dla których ten proces kończy się na 1 są liczbami szczęśliwymi, podczas gdy te, które nie kończą się na 1 są liczbami nieszczęśliwymi (lub liczbami smutnymi). Biorąc pod uwagę wydruk numeru, czy jest szczęśliwy czy nieszczęśliwy.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

Uwaga: Twój program nie powinien trwać dłużej niż 10 sekund dla dowolnej liczby poniżej 1 000 000 000.

Odpowiedzi:


8

Golfscript - 34 znaki

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

Zasadniczo taki sam jak ten i te .

Powód 9 iteracji jest opisany w tych komentarzach (teoretycznie zwraca prawidłowe wartości do około 10^10^10^974( A001273 )).


11

Ruby, 77 znaków

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

Ok, więc trochę rozumiem, jak to działa (dosłownie biorąc każdą liczbę, dzieląc ją i dodając kwadrat każdej cyfry), ale co z warunkiem zatrzymania (a <5) i używając (a <2), aby zdecydować, czy jest szczęśliwy albo nie? Nie kwestionuję ważności, tylko logikę.
Pan Llama,

2
To jest to samo co a <= 4i a <= 1. Jeśli cykl ma 1, to jest szczęśliwy, a jeśli ma 4, to nie jest szczęśliwy. Zobacz sekcję wikipedii o nieszczęśliwym cyklu. Kiedy więc wartość awynosi 4 lub mniej, sprawdza, czy jest - wynikiem jest twoja odpowiedź.
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");}

Wykorzystuje tablicę 2 30- bajtową (1 GB) jako mapę bitową do śledzenia, które liczby napotkano w cyklu. W systemie Linux działa to faktycznie i wydajnie, pod warunkiem, że włączone jest nadmierne zaangażowanie pamięci (co zwykle jest domyślnie). Przy nadmiernym zaangażowaniu strony tablicy są przydzielane i zerowane na żądanie.

Pamiętaj, że kompilacja tego programu w systemie Linux wymaga gigabajta pamięci RAM.


1
Dlaczego potrzebujesz tego miejsca blisko takiej ilości pamięci na ten problem?
Peter Olson,

1
@Peter: Przypuszczam, że podejście polega na (naiwnym) uchwyceniu cyklu dla dowolnej liczby w dozwolonym zakresie wejściowym od 1 do 1 000 000 000. Zgadzam się jednak, że w świetle teorii szczęśliwych liczb jedyną konieczną kontrolą jest osiągnięcie liczby 4, ponieważ to jedyny cykl, jaki kiedykolwiek nastąpi.
mellamokb

Jestem ciekawy: dlaczego kompilacja wymaga tak dużo pamięci RAM?
Peter Taylor,

1
Wygląda na to, że działa dobrze w systemie Windows 7 z MSVC 10. Nie zużywa znaczącej ilości pamięci podczas kompilacji i jedynie zaznacza tablicę w pliku stronicowania (coś, co brzmi o wiele bezpieczniej niż historia, którą podłączyłeś, mówiąc o nadmiernym zaangażowaniu pamięci ;-)) .
Joey,

1
Uwielbiam naiwność tego podejścia. A nadużywanie pętli jest piękne.
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 znaków

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

Każda szczęśliwa liczba jest zbieżna do 1; każda nieszczęśliwa liczba zbiega się w cykl zawierający 4. Poza wykorzystaniem tego faktu, jest to ledwo w golfa.

(Dzięki Ventero, z którego rozwiązania Ruby stworzyłem lewę i zaoszczędziłem 6 znaków).


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

Nazywany jako etex filename.tex 34*23 + 32/2 ?(w tym znak zapytania na końcu). Spacje w wyrażeniu nie mają znaczenia.

EDYCJA: przeszedłem do 123 , ale teraz wyjście to dvi (jeśli skompilowane z etex) lub pdf (jeśli skompilowane z pdfetex). Ponieważ TeX jest językiem składanym, to chyba sprawiedliwe.

\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 znaków

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

Inspiracje zaczerpnięte z Ventero i Petera Taylora.


2
lepiej robić int(c)niż niż 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')

Wprowadzanie odbywa się poprzez ustawienie a na żądaną liczbę.

Kredyty dla mellamokb.


Zaoszczędź 1 znak:n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
mellamokb

@mella Dzięki. Ogoliłem też inny zwęgiel, zmieniając ||na |.
Peter Olson,

Zapisz 8 znaków: Usuń n==4?h.... Zmień na czyn ... podczas pętli z warunkiem while(n>4). Zamiast tego użyj tego końcowego oświadczenia:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb

@Mella Clever, podoba mi się.
Peter Olson,

@Mella n musi zostać zdefiniowana przed pętlą while, próbuję wymyślić, jak się nie powtarzaćn=0;
Peter Olson,

4

Python (98, ale zbyt popsuty, by go nie udostępniać)

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

Zbyt długo, by być konkurencyjnym, ale być może dobrym do śmiechu. Dokonuje „leniwej” oceny w Pythonie. Naprawdę całkiem podobny do wpisu Haskell, kiedy o tym myślę, tylko bez uroku.


4

dc - 47 znaków

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

Krótki opis:

I~: Uzyskaj iloraz i resztę, dzieląc przez 10
d*.: Kwadrat reszty.
0<H: Jeśli iloraz jest większy niż 0, powtarzaj rekurencyjnie.
+: Zsumuj wartości podczas zmniejszania stosu rekurencyjnego.

4<h: Powtórz bit sumy kwadratów, gdy wartość jest większa niż 4.


4

Befunge, 109

Zwraca poprawne wartości dla 1 <= n <= 10 9 -1.

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

3

J, 56

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

Czasownik zamiast samodzielnego skryptu, ponieważ pytanie jest dwuznaczne.

Stosowanie:

   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 znaków

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
Czy nie (n*n)byłby krótszy n*n , czy białe znaki nie wystarczają do oddzielenia wyrażenia if od else?
Peter Taylor

Tak, zrobiłem to, Peter.
użytkownik nieznany

Oto 126- 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")
bajtowa

@ 6infinity8: Dlaczego nie opublikujesz go jako nowej odpowiedzi?
użytkownik nieznany

Początkowy post jest stary; Właśnie próbowałem ulepszyć twoje rozwiązanie.
6infinity8

3

J (50)

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

Jestem pewien, że bardziej kompetentny J-er, niż mogę to uczynić jeszcze krótszym. Jestem względnym nowicjuszem.

Nowe i ulepszone:

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

Nowsze i jeszcze bardziej ulepszone dzięki ɐɔıʇǝɥʇuʎs:

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

1
Możesz zdobyć postać, nie dzieląc „appy”. Myślę, że możesz także usunąć nawiasy wokół d ("." 0) - przysłówki wiążą się mocniej niż spójniki.
Jesse Millikan

Nie mogę usunąć nawiasów ("."0). Powoduje to błąd rangi, ale jeśli nie podzielę „Szczęśliwego” i nie zostawię wyniku w polu, mogę zapisać postać.
Gregory Higley,

Powodem, dla którego nie mogę pominąć nawiasów, ("."0)jest to, że spójniki mają zastosowanie do całego poprzedzającego zestawu czasowników, do których są dołączone, co nie jest tym, czego chcę. Jeśli powiem +/@:("."0)@":, to bardzo różni się od tego +/@:"."0@:, co jest w rzeczywistości (+/@:".)"0@:.
Gregory Higley

1
Ogromne nekro, ale możesz zapisać 4 znaki, zastępując 'Unhappy';'Happy'je Unhappy`Happy.
15ıʇǝɥʇuʎs

@ Thatıʇǝɥʇuʎs To działa, ale gdzie jest udokumentowane, że można pominąć cytowanie ciągów za pomocą `?
Gregory Higley,

2

Python (91 znaków)

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

Bardziej czytelny:

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

Krótsze byłoby po prostu zwrócenie „Szczęśliwego” lub „Nieszczęśliwego” od razu (do), ale prawdopodobnie nie byłoby to liczone jako cały program



2

Galaretka , 17 bajtów (niekonkurencyjna *)

* Wyzwanie po dacie językowej

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

Wypróbuj online!

W jaki sposób?

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 bajtów

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

$ n jest wartością wejściową


1

05AB1E , 21 bajtów

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

Wypróbuj online lub sprawdź pierwsze 100 przypadków testowych .

Wyjaśnienie:

Każda liczba ostatecznie spowoduje albo, 1albo 4, więc zapętlamy w nieskończoność i zatrzymamy się, gdy tylko liczba spadnie poniżej 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)

Zobacz moją wskazówkę 05AB1E (sekcja Jak korzystać ze słownika? ), Aby zrozumieć, dlaczego tak 'ŽØjest "happy".


0

C ++ 135, 2 linie

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

To jest zmodyfikowana wersja tej, którą tutaj zrobiłem:

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


Co to &999zrobić? I jak to działa, jeślij wartość śmieci jest wartością?
David mówi Przywróć Monikę

@ Dgrin91, napisałem to 3 lata temu, więc nie pamiętam dokładnie, jak to działa. Myślę, że & 999 wypowiada zdanie if(j==999){n = 0;}else{n=n*n +i;}, j nie powinno być wartością śmieciową, globały są inicjowane na zero.
Scott Logan

0

Tak, wyzwanie to trwa trzy lata; tak, ma już odpowiedź zwycięzcy; ale ponieważ nudziłem się i robiłem to dla kolejnego wyzwania, pomyślałem, że mogę to tutaj postawić. Niespodzianka niespodzianka, jej długi - i ...

Java - 280 264 bajtów

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

Nie golfowany:

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 bajtów

Aktualizacja: Usunięto niepotrzebne let powiązanie.

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

Oryginalny:

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

Pierwszy raz używając zagnieżdżonego for: o


0

R, 117 91 bajtów

-16 bajtów dzięki Giuseppe

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

1
Użyj strtoizamiast as.numerici pastezamiast as.character, ale istnieje krótsze podejście do uzyskania cyfr . Jeśli użyjesz `if`(a-1,"unhappy","happy")zamiast tego, powinien zapisać kolejny bajt. Na koniec możesz uczynić to anonimowym, aby zgolić jeszcze kilka bajtów.
Giuseppe,



-1

C: 1092 znaków

#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
Witamy w Programowanie Puzzle i Code Golf, @jannat. Pamiętaj, że kod golfowy to wyzwanie polegające na napisaniu możliwie najkrótszego kodu. Oznacza to, że tutaj piszemy niezauważalny i prawie nieczytelny kod i wymuszamy ograniczenia składni języka, aby skrócić nasze kody, jak to możliwe.
manatwork

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.