代码高尔夫:快乐的头号!

现在是星期天,一轮高尔夫球代码的时间!

挑战

按字符数计算最短的源代码,以确定input数字是否为“开心素数”,“悲伤素数”,“快乐非素数”或“伤心非素数”。

input

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

产量

输出应打印的数字types:“开心总理”,“悲伤素”,“开心非素数”或“伤心非素数”。 尾随的换行符是可选的。

例子

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

定义

以防万一你的大脑需要复习。

快乐的数字

从维基百科,

一个快乐的号码是由以下过程定义的。 以任何正整数开始,用数字的平方和来replace数字,并重复该过程直到数字等于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

素数

质数是一个大于1的整数,正好有两个除数:1和它自己。

快乐总理

因此,一个幸福的总理,是一个既幸福又美满的数字。

答案select

显然,答案将是字符计数的最短源代码,在我testing的所有情况下都会输出指定的结果。 一旦下一个(社区决定的)高尔夫球挑战赛来临,我会标记答案,所以我们可以集中所有的精力。 🙂

决策

那么看起来好像在城里有一个新的高尔夫代码,而且这个问题已经发布了大约一个星期了,所以我已经标记了最短的源代码作为答案(gnibbler的64个字符Golfscript解决scheme)。 也就是说,我喜欢Belisarius的99个字符Mathematica解决scheme和Nabb的神秘的107字符dc解决scheme。

对所有其他人来说,伟大的工作 我从来没有在我的电脑上有这么多的编程语言环境。 我希望每个人都学习一些新的,肮脏的手段,为他们最喜欢的语言。

重用

我已经重新发布了一些本次竞赛产生的代码,作为我编写的一个脚本的例子,用来testing各种程序与自动评分的参考实现。 该目录中的自述文件解释了源代码的来源,并指出所有代码都在CC BY-SA 2.5许可下重新使用(如SO的法律部分所述 )。 在提交时,每个目录都标有显示名称。

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

GolfScript – 64个字符(为1工作)

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

这个程序进行n次迭代来确定数字的快乐程度,这对于大数量来说是非常浪费的,但是代码高尔夫并不是为了节省字符以外的资源。 主要testing同样效率低下 – 将n除以所有从1n的值,并检查是否有余数为零的两个值。 所以虽然在理论上是正确的,但是在真正的计算机上运行真正的大数字是不现实的

GolfScript – 63个字符 (失败1)

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

直stream – 98个字符

 $ 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 

Mathematica 115 108 107 102 100 99 91 87字符


87个字符

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

–Wizard先生


大猴子学了几招(91个字)

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

用%[7]调用

编辑5 – 99个字符/

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

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

编辑4 – 100个字符/

与编辑3相同,用99replace10 ^ 2(允许input值为84位)…谢谢@Greg

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

编辑3 – 102字符/

再次重做循环。

有趣的是直到最终达到1的recursion深度由(15 +参数的位数)限定。 看到这里

所以对于less于85位的数字(我认为这个限制在OP的“不用担心处理大数字”的考虑)很好,下面的代码工程

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

我将“NestWhile”更改为较短的“Nest”,因此,不需要为recursion指定停止条件,就足以对期望的recursion深度(10 ^ 2)进行硬编码。

这不是很有效率,但这是高尔夫球员的生活:D

编辑2 – 107个字符/

重做了悲伤/快乐的任务

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

所有空格/换行符(文字除外)都是可选的,并添加了可读性

说明:

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

recursion应用“函数”[加起来的平方和]直到结果为4或更小。 该function具有停滞在“1”或进入周期{4,16,37,58,89,145,42,20,4,…}的特性。

因此,当结果是“1”时,数字是“开心”,当结果是“4”时,是“悲伤”。

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

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

所以,当结果是4或更less时,我们可以停止recursion,知道只有“1”的结果会导致一个Happy数字。

也许其他的解决scheme可能会利用这个事实。

事实上,结果5和6也导致了SAD数字,但是这只给我们提高效率,而不是打高尔夫球的好处(我猜)。

编辑1 – 108个字符/

重做了循环控制逻辑

     h =打印[
         NestWhile [Plus @@(IntegerDigits @#^ 2)&,#,#> 4&] /。{1→“Happy”,_→“Sad”}
           ,如果[PrimeQ @#,“”,“非”]
           , “主要”] &

原始 – 115个字符/

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

该声明

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

执行数位和的recursion应用,直到某个值重复为止。 “不等全部”部分负责比较前面的值列表。 最后返回重复的数值,即Happy Numbers的“1”。

样品运行

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

循环(稍微改变打印语句)

 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 

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上 ,它只是超过了一半的尺寸!

C#, 380 378 374 372 364 363 315 280 275 274字符

通过用嵌套循环replacerecursion函数,我能够将笔画计数设置为280(比原来less100)。

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

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' 

词法分析器能够将0if2for分成两个令牌,每个对我来说都是一个很好的惊喜:)(它不能和else工作)

函数s (sad)是recursion的,并且接收循环中先前数字的列表作为其第二个参数。 原始性是使用正则expression式技巧内联testing的。

通过使用废弃的`n`语法而不是str(n) ,可以进一步减less4个字符的字符数,但是我select不使用它。

C, 188 187 185 184 180 172 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 

这是一个永远不会returnrecursion函数,但是在完成时调用它自己或打印输出。 recursion函数将平方的数字相加并确定两个for循环中的素数。 scanf返回1作为h()的参数,保存一个; 和一个1 (代价是不得不使用前缀++p代替postfix p++ ,这会使得p>C可能,而不是p>=C

r&~5对于1 4 r&~50 ,其中1表示快乐,其他悲伤。

下一步尝试:drop h()并使main()recursion。

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" 

换行是可选的。

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

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

上面的代码应该在浏览器中工作,没有额外的function和特性(比如Array.prototype.indexOf[]string表示法),但是我没有在Firefox之外testing过。

请注意,除n之外的所有variables都是全局variables(我只是很便宜)。

用法

 h(139) // returns "happy prime" 

哈斯克尔172

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

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方法作为练习留给读者的地方;)

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 

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

Java: 294 286 285 282 277 262 260个字符


  • 更新1 :用正则expression式replaceBigInteger#isProbablePrime() 。 保存了8个字符。

  • 更新2 :用& (oops)代替&& 。 已保存1个字符。

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

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

  • 更新5 :用for循环replace正则expression式,重构循环的一点点。 保存了15个字符。

  • 更新6 :用long/Longreplaceint/Integer 。 保存了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-"); } } 

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 

结合C和Perl

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 

C ++, 258 231 230 227字符

 #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")<<(im?" non-":" ")<<"prime\n";}} 

不是最好的高尔夫语言,无论如何都给了它一个好机会。 这大部分是直的,所以在C中可能会更短。

编辑

一般来说整理一下,觉得现在已经是极限了,没有一个完整的重写。

也忘了补充说,这假定没有数字与一个序列超过0xFFFF数字这是一个非常合理的假设。

编辑2

修复了一个错误。 重新排列,以删除过多的调用std :: cout。

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 

F#,249个字符

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

Perl, 113 109 105个字符

在这一刻击败所有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 

Clojure, 353 318 298 261 230字符

 (defn h[xm](cond(= x 1)"happy "(mx)"sad ":else(recur(reduce +(for[n(map #(-(int %)48)(str x))](* nn)))(assoc mx 1))))(println(let [x (read)](str(hx{})(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循环会比recursion短?

我读了正则expression式质数检查。 这是真棒,并删除30个字符和我clojure.contrib依赖。 我也重构了命令行parsingsomwhat和内联函数。

前高尔夫(有些过时):

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

Javascript, 192 190 185 182 165 158 chars

主要检查从N 2到平方根运行。 我浪费了几个字

在一行中:

 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/

PHP 217字符

 $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 

斯卡拉, 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"")}} 

可能还有一些改进的余地。 该死的testing1为非主要成本6个字符:-(

Python( 285 270 269 246 241 247 240 237个字符, 21 20 21 18 19行)

 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

Python 2.6, 300 298 294 chars

Different from previous answer in that this doesn't use regex.

I'm sure there's some way of shortening my h(x) function, but I'm still learning Python so I've got no idea.

p(x) returns True if it's a non-prime. h(x) returns True if it's happy. I've done the t = True so that it shortens the character count when doing the truth check.

 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' 

Python, 169 168 158 157 166 164 162 chars, 4 lines

 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" 

Takes a number from stdin and doesn't muck around with regexes like the other python answer, although I must admit that is pretty cool. I could also shave off 6 chars by using backticks instead of the str-function, but let's play nice.

EDIT: Fixed a bug with 1 being a prime, which bumped up the charcount by 10. I figure there must be a more concise way than mine for doing this.

EDIT 2: Apparently, python 2.6 allows print[1, 2] without a space between the two.

EDIT 3: Used another calculation for the happy numbers

Python – 142 chars

I was playing around with this idea, but it turned out too long. Perhaps someone can find a way to make it shorter. Maybe it'll turn out better in Ruby. Should be fun to understand how it works anyway 🙂

 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] 

GNU sed, 146 125 chars

Run with sed -rf file. Using -r saves 5 backslashes.

Needs bc , printf , and a shell with support for here-strings.

 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 chars (needs neither printf nor here-strings)

Uses the more standard traditional yes and head instead of 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 chars (slightly bad formatted output)

Slightly shorter version, doesn't respect output formatting (has extra spaces and a newline between happy/sad and (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/