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
, printf
y 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 yes
y en head
lugar 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
porlong/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, 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 = True
para 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 :-(