Tìm xem một số có hạnh phúc hay không?


21

Một số hạnh phúc được xác định bởi quá trình sau đây. Bắt đầu với bất kỳ số nguyên dương nào, thay thế số bằng tổng bình phương các chữ số của nó và lặp lại quy trình cho đến khi số đó bằng 1 (nơi nó sẽ ở lại) hoặc nó lặp lại vô tận trong một chu kỳ không bao gồm 1. Những số đó trong đó quá trình này kết thúc bằng 1 là những con số hạnh phúc, trong khi những con số không kết thúc bằng 1 là những con số không vui (hoặc những con số buồn). Cho một số in cho dù đó là hạnh phúc hay không hạnh phúc.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

Lưu ý: Chương trình của bạn không nên mất hơn 10 giây cho bất kỳ số nào dưới 1.000.000.000.

Câu trả lời:


8

Golfscript - 34 ký tự

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

Về cơ bản giống như cái này và cái này .

Lý do cho 9 lần lặp được mô tả trong các nhận xét này (về mặt lý thuyết này trả về các giá trị chính xác lên đến khoảng 10^10^10^974( A001273 )).


11

Ruby, 77 ký tự

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

Ok, vì vậy tôi hiểu cách thức hoạt động của nó (lấy theo từng chữ số, tách nó và thêm bình phương của mỗi chữ số), nhưng điều gì với điều kiện dừng của (a <5) và sử dụng (a <2) để quyết định xem nó có vui không hay không? Tôi không đặt câu hỏi về tính hợp lệ, chỉ là logic.
Ông Llama

2
Đó là giống như a <= 4a <= 1. Nếu chu kỳ có 1 trong đó thì nó hạnh phúc, và nếu nó có 4 trong đó thì không hạnh phúc. Xem phần wikipedia về chu kỳ không vui. Vì vậy, một khi giá trị alà 4 hoặc ít hơn, anh ta kiểm tra nếu a là - kết quả của đó là câu trả lời của bạn.
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");}

Điều này sử dụng một mảng 2 30- byte (1GB) dưới dạng bitmap để theo dõi những con số nào đã gặp phải trong chu kỳ. Trên Linux, điều này thực sự hoạt động và hiệu quả là như vậy, với điều kiện là bộ nhớ quá mức được bật (mà nó thường được mặc định). Với quá nhiều, các trang của mảng được phân bổ và không theo yêu cầu.

Lưu ý rằng việc biên dịch chương trình này trên Linux sử dụng một gigabyte RAM.


1
Tại sao bạn cần bất cứ nơi nào gần với số lượng bộ nhớ cho vấn đề này?
Peter Olson

1
@Peter: Tôi cho rằng cách tiếp cận là (ngây thơ) bắt một chu kỳ cho bất kỳ số nào trong phạm vi đầu vào được phép từ 1 đến 1.000.000.000. Nhưng tôi đồng ý rằng theo lý thuyết số hạnh phúc, kiểm tra duy nhất cần thiết là nếu đạt đến số 4, bởi vì đó là chu kỳ duy nhất sẽ xảy ra.
mellamokb

Tôi tò mò: tại sao việc biên dịch nó lại đòi hỏi nhiều RAM như vậy?
Peter Taylor

1
Xuất hiện để hoạt động tốt trên Windows 7 với MSVC 10. Không tiêu thụ bất kỳ dung lượng bộ nhớ đáng chú ý nào trong khi biên dịch và chỉ đánh dấu mảng trong tệp trang (thứ gì đó nghe có vẻ an toàn hơn câu chuyện bạn liên kết về bộ nhớ quá mức gợi ý ;-)) .
Joey

1
Tôi yêu sự ngây thơ của phương pháp này. Và việc lạm dụng các vòng lặp là đẹp.
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 ký tự

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

Mỗi số hạnh phúc hội tụ đến 1; mọi con số không vui đều hội tụ vào một chu kỳ chứa 4. Khác với việc khai thác thực tế đó, điều này hầu như không được đánh gôn.

(Cảm ơn Ventero, từ giải pháp Ruby mà tôi đã đặt biệt danh cho một mẹo và lưu 6 ký tự).


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

Được gọi là etex filename.tex 34*23 + 32/2 ?(bao gồm cả dấu hỏi ở cuối). Không gian trong biểu thức không quan trọng.

EDIT: Tôi đã xuống tới 123 , nhưng bây giờ đầu ra là dvi (nếu được biên dịch với etex) hoặc pdf (nếu được biên dịch với pdfetex). Vì TeX là ngôn ngữ sắp chữ, tôi đoán điều đó công bằng.

\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 ký tự

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

Một số cảm hứng lấy từ Ventero và Peter Taylor.


2
khấm khá hơn làm một int(c)hơn 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')

Đầu vào được cung cấp bằng cách đặt a thành số mong muốn.

Tín dụng cho mellamokb.


Lưu 1 char:n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
mellamokb

@mella Cảm ơn. Tôi cũng cạo một char khác bằng cách đổi ||sang |.
Peter Olson

Lưu 8 ký tự: Xóa n==4?h.... Thay đổi để làm ... trong khi vòng lặp với điều kiện while(n>4). Sau đó, sử dụng tuyên bố cuối cùng này thay thế:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb

@Mella Thông minh, tôi thích nó.
Peter Olson

@Mella n cần được xác định trước vòng lặp while, tôi đang cố gắng nghĩ cách không lặp lạin=0;
Peter Olson

4

Python (98, nhưng quá rối để không chia sẻ)

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

Cách, cách quá lâu để cạnh tranh, nhưng có lẽ tốt cho một tiếng cười. Nó đánh giá "lười biếng" trong Python. Thực sự khá giống với mục Haskell bây giờ mà tôi nghĩ về nó, chỉ cần không có bất kỳ sự quyến rũ.


4

dc - 47 ký tự

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

Mô tả ngắn gọn:

I~: Lấy thương số và phần dư khi chia cho 10 .
d*: Bình phương phần còn lại.
0<H: Nếu thương số lớn hơn 0, lặp lại đệ quy.
+: Tính tổng các giá trị khi thu hẹp ngăn đệ quy.

4<h: Lặp lại bit tổng bình phương trong khi giá trị lớn hơn 4.


4

Befunge, 109

Trả về giá trị đúng cho 1 <= n <= 10 9 -1.

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

3

J, 56

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

Một động từ chứ không phải là một kịch bản độc lập vì câu hỏi không rõ ràng.

Sử dụng:

   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 ký tự

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
Sẽ không (n*n)ngắn hơn n*n , hoặc khoảng trắng không đủ để tách một biểu thức if khỏi else?
Peter Taylor

Vâng, tôi đã làm như vậy, Peter.
người dùng không xác định

Đây là phiên bản đệ quy đuôi 126 byte, không khớp mẫu: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: Tại sao bạn không đăng nó dưới dạng câu trả lời mới?
người dùng không xác định

Bài viết ban đầu đã cũ; Tôi chỉ cố gắng để cải thiện giải pháp của bạn.
6 vô cực8

3

J (50)

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

Tôi chắc chắn rằng một J-er có năng lực hơn tôi có thể làm điều này thậm chí còn ngắn hơn. Tôi là người mới.

Mới và cải tiến:

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

Mới hơn và thậm chí còn được cải thiện hơn, nhờ vào ıʇǝɥʇuʎs:

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

1
Bạn có thể có được một nhân vật bằng cách không tách ra 'appy'. Tôi nghĩ bạn cũng có thể loại bỏ các dấu ngoặc đơn xung quanh ("." 0) - trạng từ liên kết chặt chẽ hơn liên từ.
Jesse Millikan

Tôi không thể xóa dấu ngoặc đơn xung quanh ("."0). Điều đó tạo ra lỗi xếp hạng, nhưng nếu tôi không tách 'Hạnh phúc' và để hộp kết quả, tôi có thể lưu một ký tự.
Gregory Higley

Lý do tôi không thể bỏ qua các dấu ngoặc đơn xung quanh ("."0)là vì các liên từ áp dụng cho toàn bộ các động từ đi trước mà chúng được gắn vào, đó không phải là điều tôi muốn. Nếu tôi nói +/@:("."0)@":, điều đó rất khác với +/@:"."0@:, đó thực sự là (+/@:".)"0@:.
Gregory Higley

1
Một hoại tử lớn, nhưng bạn có thể tiết kiệm 4 ký tự bằng cách thay thế 'Unhappy';'Happy'bằng Unhappy`Happy.
ɐɔıʇǝɥʇuʎs

@ ıʇǝɥʇuʎs Điều đó hoạt động, nhưng tài liệu ở đâu mà bạn có thể bỏ qua việc trích dẫn các chuỗi với `?
Gregory Higley

2

Con trăn (91 ký tự)

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

2

Lisp thường gặp 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"))))

Dễ đọc hơn:

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

Sẽ ngắn hơn khi chỉ trả lại "Hạnh phúc" hoặc "Không vui" ngay từ khi (do), nhưng có thể cho rằng sẽ không được tính là toàn bộ chương trình



2

Thạch , 17 byte (không cạnh tranh *)

* Thử thách sau ngày ngôn ngữ

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

Hãy thử trực tuyến!

Làm sao?

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 byte

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

$ n là giá trị đầu vào


1

05AB1E , 21 byte

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

Hãy thử trực tuyến hoặc xác minh 100 trường hợp thử nghiệm đầu tiên .

Giải trình:

Mỗi số cuối cùng sẽ dẫn đến một trong hai 1hoặc 4, vì vậy chúng tôi lặp vô hạn và dừng lại ngay khi số dưới 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)

Xem mẹo 05AB1E này của tôi (phần Làm thế nào để sử dụng từ điển? ) Để hiểu tại sao 'ŽØ"happy".


0

C ++ 135, 2 dòng

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

Đây là phiên bản sửa đổi của cái tôi đã làm ở đây:

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


Làm là &999gì Và làm thế nào nó hoạt động nếu jlà một giá trị rác?
David nói Phục hồi lại

@ Dgrin91, tôi đã viết cái này 3 năm trước, vì vậy tôi không thể nhớ chính xác nó hoạt động như thế nào. Tôi nghĩ rằng & 999 đưa ra tuyên bố if(j==999){n = 0;}else{n=n*n +i;}, j không nên là một giá trị rác, toàn cầu là không khởi tạo.
Scott Logan

0

Vâng, thử thách này có ba năm; vâng, nó đã có câu trả lời chiến thắng; nhưng vì tôi đã chán và thực hiện điều này cho một thử thách khác, tôi nghĩ rằng tôi có thể đưa nó lên đây. Bất ngờ bất ngờ, lâu dài - và trong ...

Java - 280 264 byte

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

Ung dung:

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 byte

Cập nhật: Loại bỏ letràng buộc không cần thiết .

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

Nguyên:

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

Lần đầu tiên sử dụng lồng nhau for: o


0

R, 117 91 byte

-16 byte nhờ Giuseppe

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

1
Sử dụng strtoithay vì as.numericpastethay vì as.character, nhưng có một cách tiếp cận ngắn hơn để có được các chữ số . Nếu bạn sử dụng `if`(a-1,"unhappy","happy")thay thế sẽ lưu một byte khác. Cuối cùng, bạn có thể làm cho ẩn danh này để cạo thêm một vài byte.
Giuseppe



-1

C: 1092 ký tự

#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
Chào mừng bạn đến với Câu đố lập trình & Code Golf, @jannat. Xin lưu ý rằng mã golf là một thách thức của việc viết mã ngắn nhất có thể. Điều đó có nghĩa là, ở đây chúng tôi viết mã không xác định và gần như không thể đọc được và buộc các giới hạn của cú pháp ngôn ngữ để rút ngắn mã của chúng tôi càng tốt.
manatwork

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.