找出数字是否快乐?


21

通过以下过程定义一个满意的数字。从任何正整数开始,用数字的平方和代替数字,然后重复此过程,直到数字等于1(它将停留在该位置),或者它在不包含1的循环中无休止地循环。对于此过程,以1结尾的是快乐数字,而没有以1结尾的过程是不快乐数字(或悲伤数字)。给数字打印是快乐还是不快乐。

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

注意:对于任何小于1,000,000,000的数字,您的程序所花费的时间不应超过10秒。

Answers:



11

Ruby,77个字符

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

好的,我有点理解了它的工作原理(从字面上取每个数字,将其拆分并加上每个数字的平方),但是停止条件为(a <5)并使用(a <2)来确定它是否满意或不?我不怀疑有效性,只是逻辑。
骆马先生

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上编译该程序会使用1 GB的RAM。


1
为什么您需要在接近该内存量的地方解决此问题?
彼得·奥尔森

1
@Peter:我想方法是(天真的)捕捉一个周期,允许输入的范围是1到1,000,000,000。但是我同意,根据快乐数论,唯一必要的检查是是否达到数字4,因为这是唯一会发生的循环。
mellamokb 2011年

我很好奇:为什么编译它需要这么多RAM?
彼得·泰勒

1
在带有MSVC 10的Windows 7上似乎可以正常工作。编译时不消耗任何显着的内存,仅在页面文件中标记该数组(这听起来比您所链接的有关内存过量使用的故事更安全;这表明;-) 。
乔伊,

1
我喜欢这种方法的天真。而且for循环的滥用是美丽的。
dmckee 2011年


6

Golfscript,49 43 41 40 39个字符

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

每个快乐的数字收敛到1;每个不开心的数字都收敛到一个包含4的循环。除了利用这一事实之外,这几乎是毫无用处的。

(感谢Ventero,我从他的Ruby解决方案中获得了一个技巧,并节省了6个字符)。


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

称为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

Python-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

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

通过将a设置为所需的数字来提供输入。

归功于mellamokb。


节省1个字符:n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
mellamokb 2011年

@mella谢谢。通过更改||为,我还删除了另一个字符|
彼得·奥尔森

节省8个字符:删除n==4?h...。更改为do ... while条件循环while(n>4)。然后改用以下最终声明:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb

@Mella Clever,我喜欢。
彼得·奥尔森

@Mella n需要在while循环之前定义,我正在尝试思考如何不重复n=0;
Peter Olson

4

Python(98,但太混乱了,无法共享)

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

方式,距离竞争太久了,但也许会带来笑声。它在Python中执行“惰性”评估。现在我想到的确实与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

Befunge,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

Scala,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:为什么不将其发布为新答案?
不知名的使用者,2017年

最初的职位很旧;我只是想改善您的解决方案。
6infinity8年

3

J(50)

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

我敢肯定,胜任的J-er比我能做的还要短。我是一个相对较新的人。

新增和改进:

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

得益于ɐɔıʎuʎ的更新和改进:

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

1
您可以通过不分割“ appy”来获得角色。我认为您也可以删除圆括号(“。” 0)-副词的绑定比连词更紧密。
杰西·米利坎

我无法删除周围的括号("."0)。这会产生排名错误,但是如果我不拆分“ Happy”并将结果保留在方框中,则可以保存一个字符。
格雷戈里·希格利

我不能忽略括号的原因("."0)是,连词适用于它们所附加的整个先前动词系列,这不是我想要的。如果我说的话+/@:("."0)@":,那与+/@:"."0@:实际情况截然不同(+/@:".)"0@:
格雷戈里·希格利

1
大量死灵,但您可以通过替换'Unhappy';'Happy'为来节省4个字符Unhappy`Happy
ɐɔıʇǝɥʇuʎs

@ɐɔıʇǝɥʇuʎs可行,但是在哪里有记载可以跳过带有`的字符串引用?
格雷戈里·希格利

2

Python(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

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

更具可读性:

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

会更短一些,只从中返回“ Happy”或“ Unhappy” (do),但是可以说这不会算作整个程序


2

K,43

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

2

Jelly,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

Perl 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个测试用例

说明:

每个数字最终都会产生14,因此我们会无限循环,并在数字小于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是垃圾值,它将如何工作?
大卫说恢复莫妮卡2014年

@ Dgrin91,我三年前写的,所以我不记得它是如何工作的。我认为&999声明if(j==999){n = 0;}else{n=n*n +i;},j不应为垃圾值,全局变量初始化为零。
Scott Logan

0

是的,这个挑战有三年了;是的,它已经有一个赢家的答案;但是由于我很无聊,并且为了另一个挑战而这么做,所以我想把它放在这里。令人惊讶的惊喜,长期以来-在...

爪哇- 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

Clojure,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 bytes

-16 bytes thanks to Giuseppe

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.numericpaste代替as.character,但是有一种较短的方法来获得数字。如果您`if`(a-1,"unhappy","happy")改用那应该保存另一个字节。最后,您可以将该匿名用户剃掉一些字节。
朱塞佩


0

Python 2,71个字节

f=lambda n:n>4and f(sum(int(d)**2for d in`n`))or("H","Unh")[n>1]+"appy"

在线尝试!

...或者,对于相同的字节数:

f=lambda n:n>4and f(eval('**2+'.join(`n*10`)))or("H","Unh")[n>1]+"appy"

在线尝试!


-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
Welcome to Programming Puzzles & Code Golf, @jannat. Please note that code golf is a challenge of writing the shortest code possible. That means, here we write unindented and almost unreadable code and force the limits of the language syntax to shorten our codes as possible.
manatwork

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.