숫자가 행복한 지 아닌지를 찾으십니까?


21

행복한 숫자는 다음 프로세스에 의해 정의됩니다. 양의 정수로 시작하여 숫자를 자릿수의 제곱의 합계로 바꾸고 숫자가 1이 될 때까지 프로세스를 반복하거나 1이 포함되지 않은 사이클에서 끝없이 반복됩니다. 이 과정이 1로 끝나는 것은 행복한 숫자이고, 1로 끝나지 않는 것은 불행한 숫자 (또는 슬픈 숫자)입니다. 행복하든 불행하든 숫자로 인쇄되어 있습니다.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

참고 : 프로그램은 1,000,000,000 미만의 숫자에 대해 10 초 이상 걸리지 않아야합니다.

답변:



11

루비, 77 자

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

좋아, 그래서 나는 이것이 어떻게 작동하는지 (문자 그대로 각 숫자를 취하고 나누고 각 자리의 제곱을 추가하는) 방법을 얻지 만 (a <5)의 중지 조건과 (a <2)를 사용하여 행복 여부를 결정합니다. 또는 아닙니다? 나는 타당성, 논리에 의문을 제기하지 않습니다.
— Mr. Llama

2
그와 동일 a <= 4하고 a <= 1. 사이클에 1이 있으면 행복하고 4에 있으면 행복하지 않습니다. 불행주기에 대한 위키 백과 섹션을 참조하십시오 . 따라서 값 a이 4 이하이면 그는 a인지 확인합니다. 결과는 귀하의 답변입니다.
— 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");}

사이클에서 어떤 숫자가 발생했는지 추적하기 위해 2 30 바이트 (1GB) 배열을 비트 맵으로 사용합니다. Linux에서는 실제로 작동하며 효율적으로 메모리 오버 커밋 이 활성화 된 경우 (일반적으로 기본 설정 임) 오버 커밋을 사용하면 배열의 페이지가 할당되고 필요에 따라 제로화됩니다.

Linux에서이 프로그램을 컴파일하면 기가 바이트의 RAM이 사용됩니다.


1
이 문제를 해결하기 위해 메모리 용량에 가까운 곳이 필요한 이유는 무엇입니까?
— 피터 올슨

1
@Peter : 접근 방식이 1 ~ 1,000,000,000의 허용 입력 범위에있는 숫자에 대해 (순진하게) 사이클을 잡는 것으로 가정합니다. 그러나 나는 행복한 숫자 이론에 비추어, 숫자 4에 도달하면 필요한 유일한 점검은 그것이 일어날 유일한주기이기 때문에 동의한다는 것에 동의합니다.
— mellamokb

궁금합니다. 컴파일에 왜 그렇게 많은 RAM이 필요합니까?
— 피터 테일러

1
MSVC 10이 설치된 Windows 7에서 제대로 작동하는 것으로 나타납니다. 컴파일하는 동안 주목할만한 메모리 양을 소비하지 않고 페이지 파일의 배열 만 표시합니다 (메모리 오버 커밋에 대해 링크 한 내용보다 더 안전하다고 생각되는 것이 ;-)). .
— Joey

1
나는이 접근법의 순진함을 좋아한다. 그리고 for 루프의 남용은 아름답습니다.
— dmckee

6

하스켈-77

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

6

골프 스크립트, 49 43 41 40 39 자

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

모든 행복한 숫자는 1로 수렴합니다. 모든 불행한 숫자는 4를 포함하는 사이클로 수렴됩니다.

(Ventero에게 감사합니다. 그의 루비 솔루션에서 속임수를 써서 6자를 절약했습니다.)


5

이텍스, 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

etex filename.tex 34*23 + 32/2 ?(마지막에 물음표 포함)으로 호출됩니다 . 표현의 공백은 중요하지 않습니다.

편집 : 123으로 내려 갔지만 이제 출력은 dvi (로 컴파일 된 경우 etex) 또는 pdf (로 컴파일 된 경우 pdfetex)입니다. TeX는 조판 언어이므로 공평하다고 생각합니다.

\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

파이썬-81 자

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

Ventero와 Peter Taylor에서 영감을 얻었습니다.


2
일을 더 잘 int(c)보다 ord(c)-48....
— st0le

4

자바 스크립트 ( 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')

a를 원하는 숫자로 설정하여 입력합니다.

mellamokb의 크레딧.


1 개 문자 저장 :n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
— mellamokb

@mella 감사합니다. 또한로 변경 ||하여 다른 문자를 면도 했습니다 |.
— 피터 올슨

8 문자 저장 : 제거 n==4?h.... 조건이있는 루프 ...로 변경합니다 while(n>4). 그런 다음이 마지막 진술을 대신 사용하십시오.alert(["H","Unh"][n>1?1:0]+"appy")
— mellamokb

@ 멜라 클레버, 나는 그것을 좋아한다.
— 피터 올슨

@Mella n은 while 루프 전에 정의되어야합니다. 반복하지 않는 방법에 대해 생각하고 있습니다n=0;
— Peter Olson

4

파이썬 (98, 공유하지 않기로 너무 엉망)

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

길, 너무 길어서 경쟁하기는 쉽지만 아마도 웃음에는 좋습니다. 파이썬에서는 "게으른"평가를합니다. 매력이 전혀없는 것으로 생각하고있는 Haskell 항목과 매우 유사합니다.


4

dc-47 자

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

간단한 설명:

I~: 10으로 나눌 때 몫과 나머지를 가져옵니다.
d*: 나머지를 제곱합니다.
0<H: 몫이 0보다 크면 재귀 적으로 반복하십시오.
+: 재귀 스택을 축소 할 때 값을 합산합니다.

4<h: 값이 4보다 큰 동안 제곱합 비트를 반복합니다.


4

베 펀지, 109

1 <= n <= 10 9 -1에 대한 올바른 값을 반환합니다 .

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

3

J, 56

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

질문이 모호하기 때문에 독립형 스크립트가 아닌 동사입니다.

용법:

   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

스칼라, 145 자

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
하지 않을까요 (n*n)로 짧게 n*n , 또는 공백로부터는 IF 표현을 분리하기 위해 충분하지 않습니다 else?
— 피터 테일러

그렇습니다, 피터
— 사용자가 알 수 없음

패턴 일치없이 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")
— 6infinity8

@ 6infinity8 : 새로운 답변으로 게시하지 않으시겠습니까?
— 사용자가 알 수 없음

초기 게시물은 오래되었습니다. 방금 솔루션을 개선하려고했습니다.
— 6infinity8

3

J (50)

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

나는 이것을 더 짧게 만들 수있는 것보다 더 유능한 J-er이라고 확신한다. 나는 비교적 새로운 친구입니다.

새롭고 개선 된 기능 :

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

ɐɔıʇǝɥʇuʎs 덕분에 더 새롭고 더 향상되었습니다.

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

1
'appy'를 분리하지 않으면 서 캐릭터를 얻을 수 있습니다. 주변의 괄호 ( "."0)도 제거 할 수 있다고 생각합니다. 부사는 관절보다 더 단단히 묶입니다.
— Jesse Millikan

주변의 괄호를 제거 할 수 없습니다 ("."0). 순위 오류가 발생하지만 '행복'을 나누지 않고 결과를 상자에 그대로두면 문자를 저장할 수 있습니다.
— Gregory Higley

괄호를 생략 할 수없는 이유 ("."0)는 연결이 첨부 된 동사의 전체 기차에 적용되기 때문입니다. 내가 말하면 +/@:("."0)@":, 그것 +/@:"."0@:과는 실제로 다릅니다 (+/@:".)"0@:.
— 그레고리 히 글리

1
대규모 괴사가,하지만 당신은 대체하여 4 개 문자를 절약 할 수 'Unhappy';'Happy'와 함께 Unhappy`Happy.
— ɐɔıʇǝɥʇuʎs

@ ɐɔıʇǝɥʇuʎs 그것은 효과가 있지만`로 문자열의 인용을 건너 뛸 수 있다고 어디에 기록되어 있습니까?
— Gregory Higley

2

파이썬 (91 자)

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

2

커먼 리스프 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"))))

더 읽기 쉬운 :

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

에서 바로 "행복"또는 "행복 (do)하지 않음 "을 반환하는 것이 더 짧을 것입니다. 그러나 전체 프로그램으로 간주되지는 않습니다.


2

K, 43

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

2

젤리 , 17 바이트 (비경쟁 *)

* 언어 포스트 날짜 도전

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

온라인으로 사용해보십시오!

방법?

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

펄 5-77 바이트

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

$ n은 입력 값입니다


1

05AB1E , 21 바이트

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

온라인으로 시도 하거나 처음 100 개의 테스트 사례를 확인하십시오 .

설명:

각 숫자는 결국 1또는 중 하나를 초래 4하므로 무한정 반복되며 숫자가 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)

내이 05AB1E 팁을 참조하십시오 (섹션 어떻게 사전을 사용하는 방법을? ) 이유를 이해하는 'ŽØ것입니다 "happy".


0

C ++ 135, 2 줄

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

이것은 내가 한 것의 수정 된 버전입니다.

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


무엇을 &999합니까? j가비지 값 이면 어떻게 작동 합니까?
— David는 Reinstate Monica가

@ Dgrin91, 나는 3 년 전에 이것을 썼으므로 그것이 어떻게 작동하는지 정확하게 기억할 수 없습니다. & 999는 명령문을 만들고 if(j==999){n = 0;}else{n=n*n +i;}j는 가비지 값이 아니어야하며 전역은 0으로 초기화됩니다.
— Scott Logan

0

그렇습니다.이 도전은 3 년입니다. 예, 이미 승자 답변이 있습니다. 그러나 지루하고 또 다른 도전을 위해 이것을 했으므로 여기에 넣을 것이라고 생각했습니다. 놀랍고 놀랍고 오래 전부터 ...

자바 - 280 264 바이트

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

언 골프 드 :

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

클로저, 107 97 바이트

업데이트 : 불필요한 let바인딩이 제거되었습니다 .

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

기발한:

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

중첩 for: o를 사용하여 처음으로


0

R, 117 91 바이트

주세페 덕분에 -16 바이트

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

1
사용 strtoi대신 as.numeric하고 paste대신 as.character하지만,하는 짧은 접근 방식이 숫자를 얻을 수는 . `if`(a-1,"unhappy","happy")대신 사용 하면 다른 바이트를 저장해야합니다. 마지막으로이 익명으로 몇 바이트를 더 줄일 수 있습니다.
— Giuseppe



-1

C : 1092 자

#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
프로그래밍 퍼즐 및 코드 골프, @jannat에 오신 것을 환영합니다. 코드 골프는 가능한 가장 짧은 코드를 작성하는 데 어려움이 있습니다. 즉, 여기서 우리는 들여 쓰기가 거의 불가능한 코드를 작성하고 언어 구문의 한계가 코드를 최대한 짧게 만듭니다.
— manatwork

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.