Inspirado por http://xkcd.com/710/ aquí hay un código de golf para ello.
El reto
Dado un número entero positivo mayor que 0, imprima la secuencia de granizo para ese número.
La secuencia del granizo
Consulte Wikipedia para obtener más detalles.
- Si el número es par, divídelo por dos.
- Si el número es impar, triplícalo y suma uno.
Repita esto con el número producido hasta que llegue a 1. (si continúa después de 1, irá en un bucle infinito de 1 -> 4 -> 2 -> 1...
)
A veces, el código es la mejor manera de explicarlo, así que aquí hay algo de Wikipedia.
function collatz(n)
show n
if n > 1
if n is odd
call collatz(3n + 1)
else
call collatz(n / 2)
Este código funciona, pero estoy agregando un desafío adicional. El programa no debe ser vulnerable a desbordamientos de pila . Por lo tanto, debe usar iteración o recursión de cola.
Además, puntos de bonificación si puede calcular números grandes y el idioma aún no lo tiene implementado. (o si vuelve a implementar el soporte de números grandes utilizando enteros de longitud fija)
Caso de prueba
Number: 21
Results: 21 -> 64 -> 32 -> 16 -> 8 -> 4 -> 2 -> 1
Number: 3
Results: 3 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1
Además, el código golf debe incluir la entrada y salida completa del usuario.
Respuestas:
ensamblado x86, 1337 caracteres
fuente
int 23h
.Befunge
fuente
LOLCODE: 406 CHARAKTERZ
TESTD UNDR JUSTIN J. MEZA'S INTERPRETR . KTHXBYE!
fuente
Python -
95645146 caracteresObviamente no produce un desbordamiento de pila.
fuente
input
no hace uneval
.n=input()*2
Perl
Decidí ser un poco anticompetitivo y mostrar cómo codificaría normalmente ese problema en Perl.
También hay una entrada de golf de código de 46 caracteres (total) al final.
Estos tres primeros ejemplos comienzan todos con este encabezado.
Versión recursiva simple
Versión iterativa simple
Versión iterativa optimizada
Ahora voy a mostrar cómo haría ese último ejemplo con una versión de Perl anterior a la v5.10.0
Punto de referencia
Primero, el IO siempre será la parte lenta. Entonces, si realmente los comparó como están, debería obtener aproximadamente la misma velocidad de cada uno.
Para probarlos, abrí un identificador de archivo en
/dev/null
($null
) y edité cadasay $n
para leersay {$null} $n
. Esto es para reducir la dependencia de IO.Después de ejecutarlo 10 veces, aquí hay una salida de muestra representativa:
Finalmente, una entrada de código de golf real:
46 caracteres en total
Si no necesita imprimir el valor inicial, puede eliminar 5 caracteres más.
41 caracteres en total
31 caracteres para la parte del código real, pero el código no funcionará sin el
-n
interruptor. Así que incluyo el ejemplo completo en mi recuento.fuente
$i + 1
es siempre la suma (respuesta a la entrada del blog). UsarSub::Call::Recur
también es una optimización. De lo contrario, usaría@_=$n;goto &Collatz
. (Es un 10-20% más lento si cambiastate @next
amy @next
Haskell, 62 caracteres
637683,86,97,137Entrada de usuario, salida impresa, utiliza memoria y pila constantes, trabaja con enteros arbitrariamente grandes.
Una ejecución de muestra de este código, dado un número de 80 dígitos de todos los '1' (!) Como entrada, es bastante divertido de ver.
Versión original, solo función:
Haskell 51 caracteres
De todas formas, ¿quién @ & ^ # necesita condicionales?
(editar: estaba siendo "inteligente" y usé la corrección. Sin él, el código se redujo a 54 caracteres. edit2: se redujo a 51 al factorizar
f()
)fuente
c 1=[1];c n=n:(c$div(n
mod2*(5*n+2)+n)2)
- 41 caracteres, esto usa el hecho de que esto es k * (3n + 1) + (1-k) * n / 2 donde k = n mod 2Golfscript: 20 caracteres
Esto es equivalente a
fuente
21
con~
hará que el programa use un número de stdin(eval):1:in
initialize ': método indefinidoleftparen' for nil:NilClass (NoMethodError)
al reemplazar21
con~
.echo 21 | ruby golfscript.rb collatz.gs
bc 41 caracteres
Supongo que este tipo de problemas es para lo que
bc
se inventó:Prueba:
Código adecuado:
bc
maneja números con hastaINT_MAX
dígitosEditar: El artículo de Wikipedia menciona que esta conjetura ha sido verificada para todos los valores hasta 20x2 58 (aprox. 5.76e18 ). Este programa:
pruebas 2 20,000 +1 (aprox. 3.98e6,020 ) en 68 segundos, 144,404 ciclos.
fuente
cat /dev/urandom | tr -dc '0-9' | head -c 10000 | bc collatz-conjecture.bc
bc
Perl: 31 caracteres
Editado para eliminar 2 espacios innecesarios.
Editado para eliminar 1 espacio innecesario.
fuente
MS Excel, 35 caracteres
Tomado directamente de Wikipedia :
Solo fue necesario copiar / pegar la fórmula 111 veces para obtener el resultado para un número inicial de 1000.;)
fuente
C: 64 caracteres
Con soporte para enteros grandes: 431 caracteres (necesarios)
Nota : No elimine
#include <stdlib.h>
sin al menos crear un prototipo de malloc / realloc, ya que hacerlo no será seguro en plataformas de 64 bits (void * de 64 bits se convertirá a int de 32 bits).Este todavía no ha sido probado vigorosamente. También le vendría bien un poco de manteca.
Versión anterior:
(se eliminaron 12 caracteres porque nadie sigue el formato de salida ...: |)
fuente
Otra versión de ensamblador. Éste no está limitado a números de 32 bits, puede manejar números hasta 10 65534 aunque el formato ".com" que usa MS-DOS está limitado a números de 80 dígitos. Escrito para ensamblador A86 y requiere una caja DOS de Win-XP para ejecutarse. Se ensambla a 180 bytes:
fuente
dc - 24 caracteres
2528dc
es una buena herramienta para esta secuencia:También 24 caracteres usando la fórmula de la entrada de Golfscript :
57 caracteres para cumplir con las especificaciones:
fuente
Esquema: 72
Esto usa recursividad, pero las llamadas son recursivas al final, así que creo que estarán optimizadas para la iteración. En algunas pruebas rápidas, no he podido encontrar un número para el que la pila se desborde de todos modos. Solo por ejemplo:
(c)
... funciona bien. [eso es todo un número; lo acabo de romper para que quepa en la pantalla].
fuente
Mathematica, 45
50caracteresfuente
OddQ[#]
conOddQ@#
para guardar 1 carácter.c[n_]:=NestWhileList[If[OddQ@#,3#+1,#/2]&,n,#>1&]
Ruby, 50 caracteres, sin desbordamiento de pila
Básicamente una copia directa de la solución Python de makapuf :
Ruby, 45 caracteres, se desbordará
Básicamente, una copia directa del código proporcionado en la pregunta:
fuente
n.odd??
me definen. Además, eso es vulnerable a desbordamientos de pila con grandes números.p n=[n/2,n*3+1][n%2]
fuente
Python 45 Char
Afeitó un carboncillo de la respuesta de makapuf.
fuente
TI-BASIC
No es el enfoque más corto, pero sí novedoso. Seguro que se ralentizará considerablemente con secuencias grandes, pero no debería desbordarse.
fuente
Haskell: 50
fuente
c 1=[1];c n=n:(c$[n
div2,3*n+1]!!(n
mod2))
, 44 charsno es la más corta, pero sí una elegante solución clojure
fuente
C #: 216 caracteres
en forma larga:
Nueva versión, acepta un número como entrada proporcionada a través de la línea de comando, sin validación de entrada.
173154caracteres.en forma larga:
Puedo recortar algunos caracteres al copiar la idea en esta respuesta para usar un bucle for en lugar de un tiempo. 150 caracteres.
fuente
Ruby, 43 caracteres
compatible con bignum, con susceptibilidad de desbordamiento de pila:
... y 50 caracteres, compatible con bignum, sin desbordamiento de pila:
Felicitaciones a Jordan. No conocía la 'p' como reemplazo de las opciones de venta.
fuente
nroff 1
Corre con
nroff -U hail.g
1. versión groff
fuente
groff -U hail.g
y obtendrá PostScript! :-)Scala + Scalaz
Y en acción:
Scala 2.8
Esto también incluye el 1 final.
Con lo siguiente implícito
esto se puede acortar a
Editar: 58 caracteres (incluida la entrada y la salida, pero sin incluir el número inicial)
Podría reducirse en 2 si no necesita nuevas líneas ...
fuente
F #, 90 caracteres
O si no está usando F # interactivo para mostrar el resultado, 102 caracteres:
fuente
Common Lisp, 141 caracteres:
Prueba de funcionamiento:
fuente
El programa de Jerry Coffin tiene un desbordamiento de enteros, pruebe este:
probado con
El número de menos de 100 millones con el tiempo de parada total más largo es 63,728,127, con 949 pasos.
El número de menos de mil millones con el tiempo de parada total más largo es 670,617,279, con 986 pasos.
fuente
unsigned long long
.ruby, 43, posiblemente cumpliendo con el requisito de E / S
Corre con
ruby -n hail
fuente
C #: 659 caracteres con soporte BigInteger
Sin golf
fuente