student language-agnostic code-golf rosetta-stone

language agnostic - student - Code Golf: Happy Primes!



happy numbers class login (30)

GolfScript - 64 caracteres (funciona para 1)

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

Este programa hace varias iteraciones para determinar la felicidad del número, lo cual es un gran desperdicio para los grandes números, pero el código de golf no se trata de conservar recursos que no sean caracteres. La prueba principal es igualmente ineficiente: dividir n por todos los valores de 1 a n inclusive y verificar que haya exactamente dos valores con cero resto. Entonces, si bien es teóricamente correcto, ejecutar con números realmente grandes no es práctico en computadoras reales

GolfScript - 63 caracteres (falla para 1)

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

Es domingo, hora de una ronda de golf de código!

Reto

Escriba el código fuente más corto por número de caracteres para determinar si un número de entrada es "primo feliz", "primo triste", "no primo feliz" o "no primo triste".

Entrada

La entrada debe ser un entero que provenga de un argumento de línea de comando o stdin. No se preocupe por manejar números grandes, pero hágalo si puede / quiere. El comportamiento sería indefinido para valores de entrada menores que 1, pero 1 tiene un resultado definido.

Salida

La salida debe imprimir el tipo de número: "primo feliz", "primo triste", "no primo feliz" o "no primo triste". La nueva línea final es opcional.

Ejemplos

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

Definiciones

Por si acaso tu cerebro necesita un repaso.

Número feliz

De Wikipedia,

Un número feliz se define mediante el siguiente proceso. Comenzando con cualquier entero positivo, reemplaza el número por la suma de los cuadrados de sus dígitos y repite el proceso hasta que el número sea igual a 1 (donde permanecerá), o se repite sin cesar en un ciclo que no incluye 1. Esos números por lo que este proceso termina en 1 son números felices, mientras que aquellos que no terminan en 1 son números infelices (o números tristes).

Por ejemplo,

  • 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

Número primo

Un número primo es un número entero mayor que 1 y tiene precisamente dos divisores: 1 y sí mismo.

Feliz primer

Un primer feliz es, por lo tanto, un número que es a la vez feliz y primo.

Selección de respuesta

Obviamente, la respuesta será el código fuente más corto por número de caracteres que arroje los resultados especificados en todos los casos que pruebo. Marcaré la respuesta una vez que aparezca el próximo desafío de golf de código (decidido por la comunidad), para que podamos enfocar todas nuestras energías en eso. :)

Decisión

Bueno, parece que hay un nuevo código de golf en la ciudad y ha pasado aproximadamente una semana desde que se publicó esta pregunta, por lo que he marcado el código fuente más corto como la respuesta (la solución Golfscript de 64 caracteres de Golfscript ). Dicho esto, disfruté tanto de la solución Mathematica 99 caracteres de belisarius como de la solución de dc críptica de 107 caracteres de Nabb.

A todos los demás, gran trabajo! Nunca he tenido tantos entornos de lenguaje de programación en mi computadora. Espero que todos hayan aprendido algunos trucos nuevos y sucios para su idioma favorito.

Reutilizar

He vuelto a publicar parte del código producido por esta competencia como ejemplo de un script que escribí para probar varios programas en comparación con una implementación de referencia para auto-grading . El archivo README en ese directorio explica de dónde proviene el código fuente y establece que todo el código se reutiliza bajo la licencia CC BY-SA 2.5 (como se indica en la sección legal de SO). Cada directorio está etiquetado con su nombre para mostrar al momento del envío.

Si tiene un problema con la reutilización de su código de esta manera o con la atribución, avíseme y corregiré el error.


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


J: 113 caracteres

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


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

El código anterior debería funcionar en los navegadores sin funciones y funciones adicionales sofisticadas (como Array.prototype.indexOf y [] notación para cadenas), pero no lo he probado fuera de Firefox.

Ten en cuenta que todas las variables, excepto n son globales (solo estoy siendo barato).

Uso

h(139) // returns "happy prime"


Mathematica 115 108 107 102 100 99 91 87 87 caracteres

87 caracteres

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

- Sr. Asistente

Da mono aprendió algunos trucos (91 caracteres)

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

Invocar con% [7]

Edit 5 - 99 Chars /

Nueve iteraciones es suficiente. Gracias @Nabb, @mjschultz

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

Editar 4 - 100 caracteres /

Igual que la Edición 3, reemplazando 10 ^ 2 por 99 (permitiendo 84 dígitos para los valores de entrada) ... Gracias, @Greg

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

Edición 3 - 102 caracteres /

Volvió a hacer el bucle de nuevo.

Es interesante que la profundidad de la recursión hasta que finalmente llegue a 1 esté delimitada por (15 + Número de dígitos del argumento). Ver here

Entonces, para los números con menos de 85 dígitos (creo que este límite está bastante bien en la consideración de OP "No se preocupe por manejar números grandes"), el siguiente código funciona

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

Cambié el "NestWhile" para el "Nest" más corto, y así, en lugar de especificar una condición de parada para la recursión, es suficiente para codificar la profundidad de recursión deseada (10 ^ 2).

No es muy eficiente, pero esa es la vida del golfista: D

Edit 2 - 107 Chars /

Retrabajo la tarea triste / feliz

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

Todos los espacios / líneas nuevas, excepto los literales, son opcionales y se agregan para facilitar la lectura.

Explicación:

los

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

Se repite la aplicación de "función" [Suma suma de dígitos al cuadrado] hasta que el resultado sea 4 o menos. La función tiene la propiedad de que se estanca en "1", o ingresa en el ciclo {4, 16, 37, 58, 89, 145, 42, 20, 4, ...}.

Entonces, cuando el resultado es "1", el número es "Feliz" y cuando el resultado es "4", es "Triste".

Si el resultado es "2", el número también es SAD, porque entrará en el ciclo SAD en la siguiente iteración (2 ^ 2 = 4).

Si el resultado es 3, el ciclo es 3-> 9-> 81-> 65-> 61-> 37-> 58-> 89-> 145-> .... (Entra en el bucle SAD).

Por lo tanto, podemos detener la recursión cuando el resultado es 4 o menos, sabiendo que solo un resultado de "1" llevará a un número feliz.

Quizás otras soluciones puedan aprovechar este hecho.

De hecho, los resultados 5 y 6 también llevan a números SAD, pero eso nos da solo un aumento de eficiencia y no una ventaja de golf (supongo).

Editar 1 - 108 caracteres /

Rediseñado la lógica de control de bucle

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

Original - 115 caracteres /

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

La declaración

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

realiza la aplicación recursiva de las sumas de los dígitos al cuadrado, hasta que se repite algún valor. La parte "Desigual, todo" se ocupa de la comparación en la lista de valores anterior. Finalmente devuelve el valor repetido, que es "1" para números felices.

Ejecución de la muestra

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

Bucle (cambiando ligeramente la declaración de impresión)

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


Perl, 113 109 105 caracteres

¡Venciendo a todas las respuestas de Python en este momento! 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


GNU sed, 146 125 caracteres

Ejecutar con sed -rf archivo. Usando -r guarda 5 barras invertidas.

Necesidades bc, printfy una cáscara con soporte para aquí-cadenas.

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 caracteres (no necesita printf ni aquí-cadenas)

Utiliza el estándar más tradicional yesy en headlugar de 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 caracteres (salida formateada ligeramente mala)

Versión ligeramente más corta, no respeta el formato de salida (tiene espacios adicionales y una nueva línea entre feliz / triste y (no) principal)

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/


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

Al reemplazar la función recursiva con bucles anidados, pude llevar el conteo de golpes a un respetable 280 (100 menos que el original).

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

Aquí está con los espacios en blanco:

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


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

Esta es una función recursiva que nunca emite una return pero se llama a sí misma o imprime la salida cuando se realiza. La función recursiva suma dígitos cuadrados y determina la primacía en dos para los bucles. El scanf devuelve 1 que se coloca como un argumento a h() , guardando uno ; y un 1 (y al costo de tener que usar el prefijo ++p lugar del postfix p++ que haría posible p>C lugar de p>=C )

r&~5 es 0 para 1 4 5 , de los cuales 1 indica felicidad y los demás tristeza.

Siguiente intento: soltar h() y hacer main() recursivo.


Clojure, 353 318 298 261 230 caracteres

(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

Me estoy apoyando en la contribución de clojure para la secuencia de números primos. Me pregunto si el uso de bucles sería más corto que la recursión?

Leí en el cheque del número primo de expresiones regulares. Es impresionante y elimina 30 caracteres y mi dependencia de clojure.contrib. También he refaccionado la línea de comandos analizando algo y alineé una función.

Pre golf (algo desactualizado):

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


F #, 249 caracteres

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


Java: 294 286 285 282 277 262 260 caracteres

  • Actualización 1 : reemplazé BigInteger#isProbablePrime() por regex . Guarda 8 caracteres.

  • Actualización 2 : reemplazado && por & (oops). Guardado 1 char.

  • Actualización 3 : refactored s un poco. Guarda 3 caracteres.

  • Actualización 4 : la prueba en n!=1 fue superflua. Guarda 5 caracteres.

  • Actualización 5 : reemplazo de expresiones regulares por bucle y refactorizado feliz por pequeños bits de bucles. Guarda 15 caracteres.

  • Actualización 6 : reemplazado int/Integer por long/Long . Guarda 2 caracteres.

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

Con nuevas líneas:

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


Javascript, 192 190 185 182 165 158 caracteres

La comprobación principal se ejecuta desde 2 hasta la raíz cuadrada de N Perdí algunos caracteres allí ...

En una línea:

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

Formateado:

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

Compruebe: http://jsfiddle.net/TwxAW/6/


MATLAB 7.8.0 (R2009a) - 120 caracteres

Se agregaron espacios en blanco, nuevas líneas y comentarios para facilitar la lectura.

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


PHP 217 caracteres

$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";

Uso:

$ 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


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

Combinado C y Perl


Perl, 140 caracteres

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"

Los saltos de línea son opcionales.


Python - 127 caracteres

¡Venciendo ambas respuestas perl en este momento!

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

¡También GolfScript esta respuesta a GolfScript y tiene poco más de la mitad del tamaño!


Python 2.6

happy.py: 280 314 333 caracteres, 14 líneas.

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

Uso:

$ 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

-

Versión legible:

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


Python 2.6: 194 180 caracteres, 4 líneas

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

El lexer poder dividir 0if y 2for en dos tokens cada uno fue una agradable sorpresa para mí :) (aunque no funciona con else )

La función s (triste) es recursiva y recibe la lista de números anteriores en el ciclo como su segundo parámetro. La primalidad se prueba en línea usando el truco regexp .

Al usar la sintaxis `n` desuso en lugar de str(n) , uno puede reducir aún más el conteo de caracteres en 4 caracteres, pero elijo no usarlo.


Ruby 1.9

169 168 146 caracteres

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"

Si usamos p lugar de $><< , el código se reduce en 2 caracteres

Uso:

$ ruby ​​happyprime.rb 139 happy prime $ ruby ​​happyprime.rb 2 prime prime

No jugó al golf:

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

Donde el método is_prime se deja como un ejercicio para el lector;)


dc - 98 caracteres

$ 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


C ++, 258 231 230 227 caracteres

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

No es el mejor lenguaje de golf, de todos modos le dio un buen tiro. La mayor parte de esto es C recta, por lo que probablemente también sería más corto en C.

EDITAR

En general, lo ordenó, creo que está casi en el límite ahora sin una reescritura completa.

También se olvidó de agregar que esto supone que no hay números con una secuencia con más de 0xFFFF, lo que es una suposición bastante razonable.

Editar 2

arreglado un error. reorganizado para eliminar el exceso de llamadas a std :: cout.


Pitón ( 285 270 269 246 241 247 240 237 caracteres, 21 20 21 18 19 líneas)

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

EDITAR : Sí, el número aumentó, hubo un error :-P


Python - 142 caracteres

Estaba jugando con esta idea, pero resultó demasiado larga. Tal vez alguien pueda encontrar una manera de hacerlo más corto. Tal vez salga mejor en Ruby. Debería ser divertido entender cómo funciona de todos modos :)

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]


Python 2.6, 300 298 294 caracteres

Diferente de la respuesta anterior en que esto no usa expresiones regulares.

Estoy seguro de que hay alguna forma de acortar mi h(x)función, pero aún estoy aprendiendo Python, así que no tengo idea.

p(x)devuelve True si no es primo. h(x)devuelve True si es feliz. Lo he hecho t = Truepara que reduzca el recuento de caracteres al hacer la comprobación de la verdad.

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 162 caracteres, 4 líneas

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"

Toma un número de stdin y no se entremezcla con expresiones regulares como la otra respuesta de Python, aunque debo admitir que es bastante bueno. También podría eliminar 6 caracteres utilizando backticks en lugar de la función str, pero vamos a jugar bien.

EDITAR: Se corrigió un error en el que 1 era primo, lo que incrementó el conteo de caracteres por 10. Creo que debe haber una manera más concisa que la mía para hacer esto.

EDIT 2: Al parecer, Python 2.6 permite print[1, 2]sin un espacio entre los dos.

EDIT 3: utiliza otro cálculo para los números felices


VBA 245 caracteres

Buen arranque, recortará si el tiempo lo permite. Es solo mi 2do ir al código de golf!

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


MATLAB - 166 caracteres

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]

Uso

happyprime 139 ans = Happy prime


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

Probablemente haya algún margen de mejora. La maldita prueba de 1 como no principal cuesta 6 caracteres :-(