Code Golf:Happy Primes!

时间:2010-08-22 22:58:03

标签: language-agnostic code-golf rosetta-stone

这是周日,一轮代码高尔夫的时间!

挑战

按字符数编写最短的源代码,以确定输入数字是“幸福素数”,“悲伤素数”,“快乐非素数”还是“悲伤非素数”。

输入

输入应该是来自命令行参数或stdin的整数。不要担心处理大数字,但如果可以/想要这样做。对于小于1的输入值,行为将是未定义的,但1具有明确的结果。

输出

输出应打印数字类型:“快乐素数”,“悲伤素数”,“快乐非素数”或“悲伤非素数”。尾随换行符是可选的。

实施例

$ happyprime 139
happy prime
$ happyprime 2
sad prime
$ happyprime 440
happy non-prime
$ happyprime 78
sad non-prime

解释

以防你的大脑需要复习。

快乐号码

来自维基百科,

  

happy number由。定义   以下过程。从任何开始   正整数,替换数字   通过它的平方和   数字,然后重复这个过程   数字等于1(它会在哪里   留下来,或者它无休止地循环   循环不包括1.那些   此过程结束的数字   1是快乐的数字,而那些   不要以1结尾是不愉快的数字   (或悲伤的数字)。

例如,

  • 139
  • 1 ^ 2 + 3 ^ 2 + 9 ^ 2 = 91
  • 9 ^ 2 + 1 ^ 2 = 82
  • 8 ^ 2 + 2 ^ 2 = 68
  • 6 ^ 2 + 8 ^ 2 = 100
  • 1 ^ 2 + 0 ^ 2 + 0 ^ 2 = 1

素数

prime number是一个大于1的整数,并且恰好有两个除数:1和它本身。

Happy Prime

一个幸福的素数,因此是一个既快乐又优质的数字。

答案选择

显然,答案将是按字符数排序的最短源代码,在我测试的所有情况下输出指定的结果。一旦下一个(社区决定)代码高尔夫挑战出现,我将标记答案,因此我们可以将所有精力集中在那个。 :)

决策

好吧,看起来镇上有一个新的代码高尔夫,自问题发布以来已经有一周了,所以我将最短的源代码标记为答案(gnibbler的64个字符{{3}解决方案)。也就是说,我很喜欢belisarius的99个字符Golfscript解决方案和Nabb的神秘107字符Mathematica解决方案。

对所有其他人来说,干得好!我的计算机上从未有过如此多的编程语言环境。我希望每个人都为自己喜欢的语言学习一些新的,肮脏的技巧。

重用

我已经重新发布了本次竞赛产生的一些代码作为我编写的脚本示例,以针对dc的参考实现测试各种程序。该目录中的README解释了源代码的来源,并声明所有代码都在CC BY-SA 2.5许可下重新使用(如SO auto-grading中所述)。每个目录在提交时都标有您的显示名称。

如果您的代码以这种方式重新使用或归因有问题,请告诉我,我将更正错误。

33 个答案:

答案 0 :(得分:67)

dc - 98 chars

$ cat happyprimes
[happy][sad]?dsI[[I~d*rd0<H+]dsHxd4<h]dshx[r]sr1=rP[ ][ non-]_1lI[1-d2>rdlIr%0<p]dspx-2=rP[prime]p
$ echo 1  |dc happyprimes
happy non-prime
$ echo 139|dc happyprimes
happy prime
$ echo 2  |dc happyprimes
sad prime
$ echo 440|dc happyprimes
happy non-prime
$ echo 78 |dc happyprimes
sad non-prime

答案 1 :(得分:29)

Mathematica 115 108 107 102 100 99 91 87 Chars


87个字符

Print[If[Nest[Tr[IntegerDigits@#^2]&,#,9]>1,Sad,Happy],If[PrimeQ@#," "," non-"],prime]&

- Mr.Wizard


Da monkey学到了一些技巧(91个字符)

 Print[
       If[Nest[Plus@@(IntegerDigits@ #^2) &, #, 9] > 1, Sad, Happy ],
       If[PrimeQ@#, " ", " non-"], prime
      ] &

调用            %[7]

编辑5 - 99 Chars /

九次迭代就足够了。谢谢@Nabb,@ mjschultz

h = Print[
    If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 9] > 1, "Sad ", "Happy "]
   , If[PrimeQ@#, "", "non-"], "prime"] &

编辑4 - 100 Chars /

与编辑3相同,将10 ^ 2替换为99(允许输入值为84位)...谢谢,@ Greg

h = Print[
    If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 99] > 1, "Sad ", "Happy "]
   , If[PrimeQ@#, "", "non-"], "prime"] &

编辑3 - 102 Chars /

再次重写循环。

有趣的是,直到最终达到1的递归深度受到(15 +参数的位数)的限制。见here

因此对于少于85位的数字(我认为这个限制非常适合OP的“不要担心处理大数字”的考虑)以下代码可以使用

h = Print[
    If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 10^2] > 1, "Sad ", "Happy "]
   , If[PrimeQ@#, "", "non-"], "prime"] &

我为较短的“Nest”更改了“NestWhile”,因此,不是为递归指定停止条件,而是足以硬编码所需的递归深度(10 ^ 2)。

效率不高,但那是高尔夫球手的生活:D

编辑2 - 107 Chars /

重写悲伤/快乐作业

h = Print[
     If[NestWhile[Plus @@ (IntegerDigits@#^2) &, #, # > 4 &] > 1,"Sad ","Happy "]
    ,If[PrimeQ@#, "", "non-"]
    , "prime"] &

除了文字之外的所有空格/换行都是可选的,并且为了便于阅读而添加

说明:

    NestWhile[Plus @@ (IntegerDigits@#^2) &, #, # > 4 &]

递归应用“函数”[加上平方数加总和]直到结果为4或更小。该函数具有停滞在“1”或进入循环{4,16,37,58,89,145,42,20,4,...}的特性。

因此,当结果为“1”时,数字为“快乐”,当结果为“4”时,结果为“悲伤”。

如果结果为“2”,则该数字也是SAD,因为它将在下一次迭代中进入SAD循环(2 ^ 2 = 4)。

如果结果为3,则该循环为3-> 9-> 81-> 65-> 61-> 37-> 58-> 89-> 145-> ....(进入SAD循环)。

因此,当结果为4或更小时,我们可以停止递归,因为只知道“1”的结果将导致Happy数字。

也许其他解决方案可能会利用这一事实。

事实上,结果5和6也会导致SAD数字,但这只会提高效率而不是高尔夫优势(我猜)。

编辑1 - 108个字符/

重写了循环控制逻辑

    h = Print[
        NestWhile[Plus@@(IntegerDigits@#^2) &, #, #>4 &] /.{1 →"Happy ",_→"Sad "}
          , If[PrimeQ@#, "", "non-"]
          , "prime"] &

原创 - 115 Chars /

h = Print[
    If[NestWhile[Plus @@ (IntegerDigits@#^2) &, #, Unequal, All] == 1
        ,"Happy ", "Sad "],      
    If[PrimeQ@#, "", "non-"], "prime"] &

声明

NestWhile[Plus @@ (IntegerDigits@#^2) &, #, Unequal, All]

执行平方数字和的递归应用,直到某些值重复。 “Unequal,All”部分负责比较前面的值列表。最后返回重复值,对于Happy Numbers来说是“1”。

样品运行

h[7]
Happy prime
h[2535301200456458802993406410753]
Sad non-prime

循环(略微更改Print语句)

1 Happy non-prime
2 Sad prime
3 Sad prime
4 Sad non-prime
5 Sad prime
6 Sad non-prime
7 Happy prime
8 Sad non-prime
9 Sad non-prime
10 Happy non-prime
11 Sad prime
12 Sad non-prime
13 Happy prime

答案 2 :(得分:19)

GolfScript - 64个字符(适用于1)

~:@.{0\`{15&.*+}/}*1=!"happy sad "6/=@,{@\)%!},,2=4*"non-prime">

这个程序进行n次迭代以确定数字的幸福感,这对于大数字来说非常浪费,但代码高尔夫不是为了保存除字符之外的资源。主要测试同样效率低下 - 将n除以1n之间的所有值,并检查确切的两个值为零余数。因此,虽然它在理论上是正确的,但在真实计算机上运行非常大的数字是不切实际的

GolfScript - 63个字符(1个失败)

~:@9{0\`{15&.*+}/}*1=!"happy sad "6/=@,2>{@\%!},!4*"non-prime">

答案 3 :(得分:13)

Python - 127个字符

此时击败两个perl答案!

l=n=input()
while l>4:l=sum(int(i)**2for i in`l`)
print['sad','happy'][l<2],'non-prime'[4*all(n%i for i in range(2,n))*(n>1):]

我也将这个答案移植到GolfScript,它的大小只有1/2!

答案 4 :(得分:12)

C#, 380 378 374 372 364 363 < / strike> 315 280 275 274 Chars

通过用嵌套循环替换递归函数,我能够将笔画数量提高到280(比原来的小100)。

class P{static void Main(string[]a){var s=new System.Collections.Generic.HashSet<int>();int n=int.Parse(a[0]),p=n>1?4:0,c,d=1;for(;++d<n;)if(n%d<1)p=0;for(;n>1&s.Add(n);n=c)for(c=0;n>0;c+=d*d,n/=10)d=n%10;System.Console.Write((n>1?"sad":"happy")+" non-prime".Remove(1,p));}}

这里是空格:

class P
{
    static void Main(string[] a)
    {
        var s = new System.Collections.Generic.HashSet<int>();
        int n = int.Parse(a[0]),
            p = n > 1 ? 4 : 0,
            c,
            d = 1;
        // find out if the number is prime
        while (++d < n)
            if (n % d < 1)
                p = 0;
        // figure out happiness
        for (; n > 1 & s.Add(n); n = c)
            for (c = 0; n > 0; c += d * d, n /= 10)
                d = n % 10;

        System.Console.Write(
            (n > 1 ? "sad" : "happy")
            + " non-prime".Remove(1,p)
            );
    }
}

答案 5 :(得分:9)

C, 188 187 185 184 180 172 < / strike> 171 165

h(c,C,r,p){for(;C>1&&C%++p;);for(;c;c/=10)r+=c%10*(c%10);r&~5?h(r,C,0,1):printf(
"%s %sprime",r-1?"sad":"happy",p>=C&C>1?"":"non-");}main(c){h(c,c,0,scanf("%d",&c));}

$ ./a.out
139
happy prime

$ ./a.out
2
sad prime

$ ./a.out
440
happy non-prime

$ ./a.out
78
sad non-prime

这是一个递归函数,它永远不会发出return,但要么自己调用,要么在完成时打印输出。递归函数对平方数字求和,并确定两个for循环中的素数。 scanf返回1作为h()的参数,保存一个;和一个1(并且代价是必须使用前缀++p而不是使p++成为可能的后缀p>C,而不是p>=C

r&~5 0 1的{​​{1}}为4,其中5表示幸福,其他人表示悲伤。

下一次尝试:放弃1并使h()递归。

答案 6 :(得分:9)

Python 2.6: 194 180个字符,4行

import re
s=lambda n,l:0if n==1 else n in l or s(sum(int(a)**2for a in str(n)),l+[n])
n=input()
print['happy','sad'][s(n,[])],'non-'*bool(re.match(r'1?$|(11+?)\1+$','1'*n))+'prime'

lexer能够将0if2for分成两个令牌,这对我来说是个惊喜:)(虽然它不适用于else

函数s(悲伤)是递归的,并且接收循环中先前数字的列表作为其第二参数。 Primality使用regexp trick进行内联测试。

通过使用弃用的`n`语法而不是str(n),可以进一步将字符数减少4个字符,但我选择不使用它。

答案 7 :(得分:8)

Perl,140个字符

sub h{$_==1&& happy||$s{$_}++&& sad
||do{$m=0;$m+=$_**2for split//;$_=$m;&h}}$n=$_=pop;
die h,$",(1x$n)=~/^1?$|^(11+?)\1+$/&&"non-","prime\n"

换行符是可选的。

答案 8 :(得分:7)

MATLAB 7.8.0(R2009a) - 120个字符

为可读性添加了空格,换行符和注释

n=input('');
s=n;
c={'happy ','sad ','non-'};
while s>6,
  s=int2str(s)-48;
  s=s*s';                    %'# Comment to fix code highlighting
end;
disp([c{[s<2 s>1 ~isprime(n)]} 'prime'])

答案 9 :(得分:5)

Ruby 1.9

169 168 146个字符

 h={1=>'happy'};s=->x{y=0;(y+=(x%10)**2;x/=10)while x>0;h[y]||(h[y]='sad';s[y])}
 $><<s[n=$*[0].to_i]+" #{'non-'if '1'*n=~/^1?$|^(11+?)\1+$/}prime"

如果我们使用p代替$><<,则代码会缩短2个字符

用法:

$ ruby​​ happyprime.rb 139 快乐的素数 $ ruby​​ happyprime.rb 2 悲伤的黄金


非高尔夫:

hash = {1->'happy'}
is_happy = lambda do |number|
  #sum = number.scan(/\d/).reduce(0){|acum, digit| acum + digit.to_i ** 2 }
  sum=0; 
  while (number > 0)
      sum+= (number%10)**2
      number/=10
  end
  return hash[sum] if hash[sum] # If 1, or if cycled and hash contains the number already
  h[sum] = 'sad'
  return is_happy.call(sum)
end
number = ARGV[0].to_i
string = ""
string += is_happy.call(number) # either 'happy' or 'sad'
string += is_prime(number) ? " non-prime" : "prime"
puts string

is_prime方法留给读者的练习;)

答案 10 :(得分:5)

Javascript 244 250

function h(n){p=n=n<2?10:n;a=",";w="";s=[];while((y=a+s.join(a)+a).indexOf(a+n+a)<0){s.push(n);k=""+n;n=0;for(i=0;i<k.length;)c=k.charAt(i++),n+=c*c}w+=y.indexOf(",1,")<0?"sad ":"happy ";for(i=2;i<p;)p=p%i++?p:0;w+=p?"":"non-";return w+"prime"}

上面的代码应该可以在浏览器中使用,而不需要额外的花哨功能和特性(例如字符串的Array.prototype.indexOf[]表示法),但我没有在Firefox之外测试它。

请注意,n以外的所有变量都是全局变量(我只是便宜)。

用法

h(139) // returns "happy prime"

答案 11 :(得分:5)

Haskell 172

h s n|n`notElem`s=h(n:s)$sum[read[k]^2|k<-show n]|1`elem`s="happy "|0<1="sad "
c n|n<2||any((0==).mod n)[2..n-1]="non-"|0<1=[]
y n=h[]n++c n++"prime"
main=readLn>>=putStr.y

答案 12 :(得分:4)

Python 2.6

happy.py:280 314 333 字符,14行。

import re
def q(z):
 while z!=1:z=sum((int(a)**2 for a in `z`));yield z
def h(g):
 l=[]
 while 1:
  try:z=g.next()
  except:return 'happy '
  if z in l:return 'sad '
  l.append(z)
p=lambda n:not re.match(r'^1$|^(11+?)\1+$','1'*n)
n=int(input())
print h(q(n))+'non-prime'[4*p(n):]

用法:

$ echo 139 | python happy.py
happy prime
$ echo 2 | python happy.py
sad prime
$ echo 440 | python happy.py
happy non-prime
$ echo 1234567 | python happy.py
sad non-prime

-

可读版本:

import re, sys

def happy_generator(z):
    while z != 1:
        z = sum((int(a)**2 for a in str(z)))
        yield z

def is_happy(number):
    last = []
    hg = happy_generator(number)
    while True:
        try:
            z = hg.next()
        except StopIteration:
            return True

        if z in last:
            return False
        last.append(z)

def is_prime(number):
    """Prime test using regular expressions :)"""
    return re.match(r'^1?$|^(11+?)\1+$', '1'*number) is None

n = int(sys.argv[1])

print "%s %sprime" % (('sad','happy')[is_happy(n)], ('non-','')[is_prime(n)])

答案 13 :(得分:4)

J:113个字符

h=.1=$:@([:+/[:*:@"."0":)`]@.(e.&1 4)
1!:2&2;(({&('sad ';'happy '))@h,({&('non-prime';'prime'))@(1&p:))".(1!:1]3)

$ echo -n 7 | jc happy.ijs
happy prime
$ echo -n 139 | jc happy.ijs
happy prime
$ echo -n 2 | jc happy.ijs
sad prime
$ echo -n 440 | jc happy.ijs
happy non-prime
$ echo -n 78 | jc happy.ijs
sad non-prime

答案 14 :(得分:4)

Java: 294 286 285 282 277 262 < / strike> 260 chars


  • 更新1 :将BigInteger#isProbablePrime()替换为regex。保存了8个字符。

  • 更新2 :将&&替换为&(oops)。保存1个字符。

  • 更新3 :重构s一点。保存了3个字符。

  • 更新4 n!=1上的测试是多余的。保存了5个字符。

  • 更新5 :用for循环替换正则表达式,重构为高位循环。保存了15个字符。

  • 更新6 :将int/Integer替换为long/Long。保存了2个字符。


import java.util.*;class H{public static void main(String[]a){long n=new Long(a[0]),p=n>1?1:0,s,d=1;while(++d<n)if(n%d<1)p=0;for(Set c=new HashSet();c.add(n);n=s)for(s=0;n>0;s+=d*d,n/=10)d=n%10;System.out.printf("%s %sprime",n>1?"sad":"happy",p>0?"":"non-");}}

使用换行符:

import java.util.*;
class H{
 public static void main(String[]a){
  long n=new Long(a[0]),p=n>1?1:0,s,d=1;
  while(++d<n)if(n%d<1)p=0;
  for(Set c=new HashSet();c.add(n);n=s)for(s=0;n>0;s+=d*d,n/=10)d=n%10;
  System.out.printf("%s %sprime",n>1?"sad":"happy",p>0?"":"non-");
 }
}

答案 15 :(得分:3)

MATLAB - 166个字符

function happyprime(a)
h={'non-prime','prime'};
h=h{isprime(str2num(a))+1};
for i=1:99
   a=num2str(sum(str2num((a)').^2));
end
s={'Sad ','Happy '};
[s{(str2num(a)==1)+1},h]

用法

happyprime 139
ans =
Happy prime

答案 16 :(得分:3)

C ++, 258 231 230 227 chars

#include<iostream>
#define w while
int m,n,i,j,t=10;int main(){w(std::cin>>n){j=0,m=n;w(n>1){i=0;do i+=n%t*(n%t);w(n/=t);n=n*n+i;n=++j&0xFFFF?n:0;}i=1;w(m%++i&&j>1);std::cout<<(n?"happy":"sad")<<(i-m?" non-":" ")<<"prime\n";}}

不是最好的高尔夫语言,无论如何都给了它很好的投篮机会。大部分都是直C,所以C也可能更短。

修改

一般整理一下,认为现在几乎没有完全重写的极限。

同样忘了补充一点,假设没有带有超过0xFFFF数的序列的数字,这是一个非常明智的假设。

编辑2

修正了一个错误。重新排列以删除对std :: cout的过度调用。

答案 17 :(得分:3)

VBA 245个字符

好的首发,如果时间允许,将削减。它只是我的第二次去代码高尔夫!

Public Sub G(N)
Dim Z, D, X, O
X = N
Z = N
Do Until Z = 1 Or X > N Or X = 0
    X = 0
    For D = 1 To Len(CStr(Z))
        X = X + CLng(Mid(CStr(Z), D, 1) ^ 2)
    Next D
    Z = X
Loop
If Z = 1 Then O = "Happy" Else O = "Sad"
D = 2
Do
    If N / D = Int(N / D) Then O = O & " Not Prime": Debug.Print O: Exit Sub
    D = D + 1
Loop While D < N
O = O & " Prime"
Debug.Print O
End Sub

答案 18 :(得分:3)

Perl,135C

sub h{my$s;$s+=$_**2for split//,pop;($s-4)?($s-1)?&h($s):1:0}$a=pop;
print h($a)?happy:sad,$",(1x$a)=~/^1?$|^(11+?)\1+$/&&"non-",prime

合并CPerl

答案 19 :(得分:2)

Scala, 253 247 246

object H{def main(a:Array[String]){var s=Set(0)
val n=a(0)toInt
def r(m:Int):String={val k=""+m map(c=>c*(c-96)+2304)sum;if(k<2)"happy"else if(s(k))"sad"else{s+=k;r(k)}}
printf("%s %sprime",r(n),if(n<2|(2 to n-1 exists(n%_==0)))"non-"else"")}}

可能还有一些改进空间。对于1作为非主要费用的该死的测试费用为6个字符: - (

答案 20 :(得分:2)

F#,249个字符

let n=stdin.ReadLine()|>int
let rec s x=seq{yield x;yield!string x|>Seq.sumBy(fun c->(int c-48)*(int c-48))|>s}
printfn"%s %sprime"(if s n|>Seq.take 99|>Seq.exists((=)1)then"happy"else"sad")(if[2..n/2]|>Seq.exists(fun d->n%d=0)then"non-"else"")

答案 21 :(得分:2)

Clojure, 353 318 298 261 230 chars

(defn h[x m](cond(= x 1)"happy "(m x)"sad ":else(recur(reduce +(for[n(map #(-(int %)48)(str x))](* n n)))(assoc m x 1))))(println(let [x (read)](str(h x{})(if(re-matches #"^1$|^(11+)?\1+"(apply str(repeat x\1)))"non-""")"prime")))

ptimac:clojure pti$ clj  happy.clj 139
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
happy prime
ptimac:clojure pti$ clj  happy.clj 440
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
happy non-prime
ptimac:clojure pti$ clj  happy.clj 2
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
sad prime
ptimac:clojure pti$ clj  happy.clj 78
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
sad non-prime

我倾向于对素数序列的clojure贡献。我想知道使用for循环是否会短于递归?

我读了正则表达式素数检查。这很棒,删除了30个字符和我对clojure.contrib的依赖。我还重构了解析somwhat的命令行并内联了一个函数。

预打高尔夫球(有些过时):

(defn h[x m]
  (cond
   (= x 1) "happy "
   (m x) "sad "
   :else (recur
               (reduce +
                 (for [n (map #(- (int %) 48) (str x))] (* n n))) 
               (assoc m x 1))))

    (println
      (let [x (read)]
        (str
           (h x{})
           (if (re-matches #"^1$|^(11+)?\1+"(apply str(repeat x \1)))
             "non-"
             "")
           "prime")))

答案 22 :(得分:2)

PHP 217 Chars

$t=$argv[1];for($z=$t-1,$p=1;$z&&++$p<$t;)$z=$t%$p;$f=array(1);while(!in_array($t,$f,1)){$f[]=$t;$t=array_reduce(str_split($t),function($v,$c){return $v+=$c*$c;});}print($t<2?"happy ":"sad ").(!$z?"non-":"")."prime";

用法:

$ php -r '$t=$argv[1];for($z=$t-1,$p=1;$z&&++$p<$t;)$z=$t%$p;$f=array(1);while(!in_array($t,$f,1)){$f[]=$t;$t=array_reduce(str_split($t),function($v,$c){return $v+=$c*$c;});}print($t<2?"happy ":"sad ").(!$z?"non-":"")."prime";' 139
happy prime

答案 23 :(得分:2)

Javascript, 192 190 185 182 165 158 chars

素数检查从2N的平方根。我在那里浪费了几个字符......

在一行中:

for(x=2,y=m=n=prompt();x*x<y&&n%x++;);for(s={};!s[m];m=p)for(s[m]=1,p=0;m;m=(m-=k=m%10)/10,p+=k*k);alert((m-1?'sad':'happy')+(n-1&&x*x>y?' ':' non-')+'prime')

格式化:

// Getting the number from the input and checking for primeness
// (ie. if after the loop x>y => n is prime)
for (x=2, y=m=n=prompt(); x*x<y && n%x++;)

// Checking for happiness
// the loop is broken out of if m is already encountered
// the m==1 after the loop indicates happy number
for(s={}; !s[m]; m=p)
    for (s[m]=1, p=0; m; m=(m -= k=m%10)/10, p+=k * k);

alert((m-1 ? 'sad' : 'happy') + (n-1 && x*x>y ? ' ' : ' non-') + 'prime')

检查:http://jsfiddle.net/TwxAW/6/

答案 24 :(得分:2)

Perl, 113 109 105 chars

此时击败所有Python答案! SCNR。

$n=$s=<>;$s=0,s/\d/$s+=$&*$&/ge while($_=$s)>4;die$s>1?sad:happy,$","non-"x(1x$n)=~/^1$|(^11+)\1+$/,prime

答案 25 :(得分:1)

Python, 169 168 158 157 166 164 < / strike> 162个字符,4行

l=n=input()
while l>4:l=sum(int(i)**2for i in str(l))
print['sad','happy'][l==1and str(n)!=1],
print['non-',''][n!=1 and sum(n%i==0for i in range(1,n))<2]+"prime"

从stdin获取一个数字并且不会像其他python答案那样使用正则表达式,尽管我必须承认这很酷。我也可以通过使用反引号代替str函数来削减6个字符,但让我们玩得很好。

编辑:修正了1为素数的错误,将字符数增加了10个。我认为必须有一个比我更简洁的方法。

编辑2:显然,python 2.6允许print[1, 2]在两者之间没有空格。

编辑3 :使用了另一种计算的快乐数字

答案 26 :(得分:1)

Python( 285 270 269 246 241 247 < / del> 240 237个字符, 21 20 21 18 19行)< / H2>
n=input()
s='prime'
for i in range(2,n):
    if n%i==0: 
        s='non'+s
        break
f=list(str(n))
g=set()
while n!=1:
    n=sum([int(z)**2 for z in f])
    if n in g:
        s='sad '+s
        break
    else:
        f=list(str(n))
        g.add(n)
else:
    s='happy '+s
print s

编辑:是的,数字上升,有一个错误:-P

答案 27 :(得分:1)

Python 2.6, 300 298 294个字符

与之前的答案不同,因为这不使用正则表达式。

我确信有一些方法可以缩短我的h(x)功能,但我还在学习Python,所以我不知道。

p(x)如果是非素数,则返回True。 h(x)如果满意则返回True。我完成了t = True,以便在进行真相检查时缩短字符数。

x=input()
def p(x):
 if x==1 or 1 in [1 for i in range(2,x) if x%i==0]: return True
def h(x):
 l=[]
 while x not in l:
  l.append(x)
  x=sum([int(i)**2 for i in str(x)])
 if 1 in l: return True
if h(x):print'happy',
elif not h(x):print'sad',
if p(x):print'non-prime'
elif not p(x):print'prime'

答案 28 :(得分:1)

Python - 142个字符

我正在玩这个想法,但结果太长了。也许有人可以找到一种方法来缩短它。也许它在Ruby中会变得更好。理解它是如何工作应该很有趣:)

n=input();L=[n];print"%s non-prime"[4*([1for f in range(1,n)if L.append(sum(int(x)**2for x in`L[-1]`))or n%f<1]==[1]):]%['sad','happy'][1in L]

答案 29 :(得分:1)

GNU sed, 146 125 chars

使用sed -rf文件运行。使用-r可以保存5个反斜杠。

需要bcprintf和支持here-strings的shell。

h
s/^/printf %*s /e
s/^ $|^(  +)\1+$/non-/
s/ *$/prime/
x
:a
s/./+&*&/g
s//bc<<</e
tb
:b
s/^1$/happy/
s/^4$/sad/
Ta
G
s/\n/ /

GNU sed, 155 141个字符(既不需要printf也不需要here-strings)

使用更多标准传统yeshead代替printf

h
:a
s/./+&*&/g
s/.*/echo 0&|bc/e
tb
:b
s/^1$/happy/
s/^4$/sad/
Ta
x
s/^/yes|head -/e
s/\n//g
s/^y$|^(yy+)\1+$/non-/
s/y*$/prime/
x
G
s/\n/ /

GNU sed, 134 115个字符(格式化输出稍差)

版本略短,不尊重输出格式(在happy / sad和(non)prime之间有额外的空格和换行符。)

h
:a
s/./+&*&/g
s//bc<<</e
tb
:b
s/^1$/happy/
s/^4$/sad/
Ta
p
g
s/^/printf %*s /e
s/^ $|^(  +)\1+$/non-/
s/$/prime/

答案 30 :(得分:1)

PARI / GP

184字节

有点迟到参加,但这里有一个短暂的。

a(x,v=[])=s=0;while(x,s+=(x%10)^2;x\=10);for(k=1,length(v),if(v[k]==s,return("sad ")));return(if(s==1,"happy ",v=concat(v,s);a(s,v)));f(x)=print(a(x),if(!isprime(x),"non-",""),"prime")

使用它。写f(139)

答案 31 :(得分:0)

球拍,286个字符

唯一的问题是1是素数。

(define d
  (lambda (n)
    (cond
      ((= n 0) 0)
      ((+
       (expt (modulo n 10) 2)
       (d (floor (/ n 10)))
       ))
      )
    )
  )

(define dd
  (lambda (n l)
    (cond
      ((= n 1) "happy ")
      ((for/or ([v l]) (= n v)) "sad ")
      ((dd (d n) (cons n l)))
      )
    )
  )

(define cg
  (lambda (n)
    (display (dd n '()))
    (display
    (if
     (for/and
       ([i (in-range 2 (floor (+ (sqrt n) 1)))]) (> (modulo n i) 0))
       "prime" "non-prime"
     ))
    )
  )

答案 32 :(得分:0)

JavaScript - 171(Closure Compiler Compressed)

刚刚找到了这个有趣的挑战。这是JavaScript中的171个字符:

function h(a){for(b=2,c="";b<a;b++)a%b||(c="non-");c+="prime";for(b={};;){if(a==1)return"happy "+c;if(b[a])return"sad "+c;b[a]=1;for(e=0;a;){d=a%10;e+=d*d;a=(a-d)/10}a=e}}

我通过高级模式中的 Closure Compiler 运行源代码来压缩它。来源:

function h(num)
{
    // Check for prime-ness
    // Save the word "prime" by attaching a "non-" in front if it has a factor
    // Notice that we are not concerned with performance here, otherwise should
    // break when a factor is found and should only go up to Math.sqrt(num)

    for (var x=2, prime=""; x < num; x++) {
        if (!(num % x)) prime="non-";
    }

    // Create "prime" or "non-prime"

    prime += "prime";

    // Keep all visited numbers in a hash

    var visited = {};

    while(true) {
        // If the number is one, then happy
        if (num == 1) return "happy " + prime;

        // Otherwise put it into the hash
        if (visited[num]) return "sad " + prime;
        visited[num] = 1;

        // Recalculate the new number by shifting through each digit
        var sum = 0;
        while (num) {   // Stop when num -> 0 (i.e. no more digits)
            var digit = num % 10;
            sum += digit * digit;
            num = (num - digit)/10; // Shift by one digit
        }

        num = sum;
    }
}