Esta es la conjetura de Collatz (OEIS A006577 ):
- Comience con un número entero n > 1.
- Repita los siguientes pasos:
- Si n es par, divídalo por 2.
- Si n es impar, multiplíquelo por 3 y agregue 1.
Está comprobado que para todos los enteros positivos hasta 5 * 2 60 , o aproximadamente 5764000000000000000 , n eventualmente se convertirá en 1 .
Su tarea es averiguar cuántas iteraciones se necesitan (de reducir a la mitad o triplicar más uno) para llegar a 1 .
Reglas:
- El código más corto gana.
- Si se ingresa un número <2, o no es un número entero, o no es un número, la salida no importa.
Casos de prueba
2 -> 1
16 -> 4
5 -> 5
7 -> 16
1+
está especialmente revestido como)
.C -
5047 caracteresDesafortunadamente, el pequeño C requiere una cantidad horrible de código para E / S básicas, por lo que acortar todo eso ha hecho que la IU sea poco intuitiva.
Compilarlo con por ejemplo
gcc -o 1 collatz.c
. La entrada está en unario con dígitos separados por espacios, y encontrará la respuesta en el código de salida. Un ejemplo con el número 17:fuente
return~-a?
ahorra 1. También se debe guardarb++
el traslado al?
casob--
.Perl 34 (+1) caracteres
Abusando
$\
para la salida final, como de costumbre. Ejecute con la-p
opción de línea de comando, la entrada se toma destdin
.Salvado un byte debido a Elias Van Ootegem . Específicamente, la observación de que los dos siguientes son equivalentes:
Aunque un byte más, ahorra dos bytes acortando
$_/2
a solo.5
.Uso de la muestra:
PHP 54 bytes
La archienemigo de Javascript para el Premio Cuchara de Madera parece haberse quedado un poco corta en este desafío. Sin embargo, no hay mucho espacio para la creatividad con este problema. La entrada se toma como un argumento de línea de comando.
Uso de la muestra:
fuente
$_
en el ternario parece un desperdicio, puede afeitarse otro personaje mediante el uso de*=
la siguiente manera:$\++,$_*=$_&1?3+1/$_:.5while$_>1}{
. Multiplicar por1/$_
tiene el mismo efecto que+1
, así que$_*=3+1/$_
funciona bien$_*=3+1/$_
es brillante, ¡gracias!Mathematica (35)
Uso:
fuente
Como suelo hacer, comenzaré las respuestas con las mías.
JavaScript,
4644 caracteres (se ejecuta en la consola)fuente
Java,
165, 156, 154,134,131,129,128, 126 (los lenguajes detallados también necesitan algo de amor)Todo se hace dentro de la
Eso es malditamente hermoso hombre. Gracias a Pater Taylor !!!, y la idea de usar un bucle for fue robada a ugoren
Reemplacé Integer por Short.
fuente
i(,++y)
. Puede guardar dos más utilizando en<
lugar de==
.class a{public static void main(String[]a){for(int x=new Short(a[0]),y=0;x>1;System.out.println(++y))x=x%2<1?x/2:x*3+1;}}
Los cambios realizados: 1) SustituidoShort.valueOf(...)
connew Short(...)
de -4 bytes y 2) He puesto elx=x%2<1?x/2:x*3+1;
en el cuerpo de lafor
-loop para deshacerse de la coma por -1 byte .Rebmu : 28
En un problema tan breve y complejo, es probable que GolfScript gane un cierto porcentaje contra Rebmu (si no es necesario decirlo, lea archivos de Internet o genere archivos JPG). Sin embargo, creo que la mayoría estaría de acuerdo en que la lógica del Golfscript no es tan fácil de seguir, y la pila ejecutable total que lo ejecuta es más grande.
Aunque el propio creador de Rebol, Carl Sassenrath , me dijo que encontró a Rebmu "ilegible", está ocupado y no tiene tiempo para practicar realmente la transformación de cerdo-latín a través de unmushing . Esto realmente se transforma simplemente en:
Tenga en cuenta que se necesitaba espacio para obtener una a: en lugar de una a . Esta es una "palabra clave". y el evaluador nota ese tipo de símbolo para activar la asignación.
Si se escribiera en forma abreviada (pero Rebol escrito torpemente), obtendría:
Rebol, como Ruby, evalúa los bloques hasta su último valor. El bucle UNTIL es una forma curiosa de bucle que no tiene condición de bucle, simplemente deja de bucle cuando su bloque se evalúa como algo no FALSO o NINGUNO. Entonces, en el punto en que
1 ==
el resultado de asignar A (el argumento para rebmu) al resultado del condicional Collatz (cualquiera es un IF-ELSE que evalúa la rama que elige) ... el bucle se rompe.J y K se inicializan al valor entero cero en Rebmu. Y como se mencionó anteriormente, todo se evalúa hasta el último valor. Entonces, una referencia J al final del programa significa que obtienes el número de iteraciones.
Uso:
fuente
Python repl, 48
No estoy convencido de que no haya una expresión más corta que
n=3*n+1;n/=1+n%2*5;
. Probablemente encontré una docena de expresiones diferentes de la misma longitud ...editar: he encontrado otra solución que nunca competirá, pero es demasiado divertida para no compartirla.
fuente
(n//2,n*3+1)[n%2]
Es más corto.n/2
funcionaría tan bien como sabemos que es incluso?APL (31)
fuente
{1=⍵:0⋄2|⍵:1+∇1+3×⍵⋄1+∇⍵÷2}
{1=⍵:0⋄1+∇⊃⍵⌽0 1+.5 3×⍵}
J, 30 caracteres
Resultó bastante más de lo deseado
uso:
-:`(1+3&*)`]
es un gerundio compuesto por tres verbos, usado en tres ocasiones.-:
significa "reducir a la mitad"(1+3&*)
o(1+3*])
codifica el paso de multiplicación y la]
terminación de las ayudas (de identidad).2&|+1&=
forma un índice para el gerundio. literalmente, "el resto después de la división por dos más si es igual a uno".#verb^:a:
itera la función hasta que el resultado sea estable (aquí, forzado explícitamente), mientras recopila los pasos, luego los cuenta. Robado de @JB .<:
disminuye el recuento de pasos en uno para alinearse con los requisitos de la pregunta.fuente
<:
,#-:
,:`(
,&*)
,=)
,)^:
.<:
significa "decremento" o "menos o igual",#
significa "conteo de" o "n veces",-:
significa "reducir a la mitad" o "igualdad de épsilon",:`(
significa a su vez el final de dicha "reducción a la mitad", el vínculo entre dos verbos en un gerundio y un paréntesis izquierdo (usado para agrupar).&*)
significa "algo unido a la multiplicación" (3 unidos con la multiplicación crea el operador "multiplicado por tres") y el final de la agrupación.=
realiza comprobaciones de igualdad o, en sentido unario, autoclasificación.^:
es la conjunción de poder (iteración verbal). Como muchos verbos J terminan con dos puntos, ... :-)<:#a:2&(<*|+|6&*%~)
19 bytes (-11)Esquema de Gambito,
10698 caracteres, 40 paréntesis(let((f(lambda(x)(cond((= x 1) 0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))))(f(read)))
9189 caracteres con definir directamente(define(f x)(cond((= x 1)0)((odd? x)(+ 1(f(+ 1(* 3 x)))))(else(+ 1(f(/ x 2))))))(f(read))
fuente
PowerShell:
7774717061Código de golf:
Notas:
Originalmente intenté tomar la entrada del usuario sin forzarla a un número entero, pero eso se rompió de una manera interesante. Cualquier entrada impar se procesaría incorrectamente, pero incluso las entradas funcionarían bien. Me tomó un minuto darme cuenta de lo que estaba pasando.
Al realizar la multiplicación o suma, PowerShell trata primero la entrada sin escribir como una cadena. Entonces, se
'5'*3+1
convierte en '5551' en lugar de 16. Las entradas pares se comportaron bien porque PowerShell no tiene una acción predeterminada para la división contra cadenas. Incluso las entradas pares que progresarían a través de números impares funcionaron bien porque, para cuando PowerShell llegó a un número impar en el ciclo, la variable ya estaba forzada a un entero por las operaciones matemáticas de todos modos.Consejo de golfista de PowerShell: Para algunos escenarios, como este,
switch
lateif/else
. Aquí, la diferencia fue de 2 personajes.No hay comprobación de errores para valores no enteros o enteros menores de dos.
Si desea auditar la secuencia de comandos, coloque
;$i
justo antes de la última llave de cierre en la secuencia de comandos.No estoy seguro de qué tan bien PowerShell maneja los números que progresan en valores muy grandes, pero espero que la precisión se pierda en algún momento. Desafortunadamente, también espero que no se pueda hacer mucho al respecto sin inflar seriamente el script.
Código sin golf, con comentarios:
Casos de prueba:
A continuación se muestran algunos ejemplos con la auditoría habilitada. También he editado el resultado para mayor claridad, agregando etiquetas a la entrada y al conteo final y colocando espacios para separar los valores de Collatz.
Bits interesantes sobre los números de entrada que no son de los casos de prueba de la pregunta:
14
y197
son Keith Numbers31
es un primer Mersenne6174
es la constante de Kaprekar8008135
. Y Numberphile , obviamente.fuente
switch
con$i=(($i/2),($i*3+1))[$i%2]
read-host
a número, solo cambie$i*3
a3*$i
.$i*3
por qué no pensé en eso ya?param($i)for(;$i-ne1;$x++){$i=(($i/2),(3*$i+1))[$i%2]}$x
- intercambie el host de lectura por un parámetro, para obtener 56 bytes . Enlace de prueba en línea80386 conjunto, 16 bytes
Este ejemplo usa la sintaxis de AT&T y la convención de llamada de llamada rápida, el argumento entra en
ecx
:Aquí están los 16 bytes resultantes de código de máquina:
fuente
Brachylog , 16 bytes
Pruébalo en línea!
Explicación
Una solución alternativa en el mismo número de bytes:
Pruébalo en línea!
fuente
GolfScript (23 caracteres)
Prueba en línea
fuente
F # - 65 caracteres
fuente
Python
68585452 caracteresf=lambda n:1+(n-2and f((n/2,3*n+1)[n%2]));f(input())
Gracias a Bakuriu y a Boothby por los consejos :)
fuente
n%2and 3*n+1or n/2
para guardar 5 caracteres. También en python2 puede eliminar la llamada aint
, reduciendo el tamaño a 58 bytes.[n/2,3*n+1][n%2]
.unsupported operand type(s) for -: 'str' and 'int'
Retina , 43 bytes
Toma entrada e imprime la salida en unario.
Cada línea debe ir a su propio archivo. 1 byte por archivo adicional agregado al conteo de bytes.
Puede ejecutar el código como un archivo con la
-s
bandera. P.ej:El algoritmo es un ciclo de hacer un paso de Collatz con el número unario y agregar un nuevo marcador de paso
x
al final de la cadena si el número no es 1.Cuando el ciclo termina con
1
, convertimos los marcadores a un número unario (eliminando el inicio1
) que es la salida deseada.fuente
Gelatina , no competidora
12 bytes Esta respuesta no es competitiva, ya que el desafío es anterior a la creación de Jelly.
Pruébalo en línea!
Cómo funciona
fuente
dc, 27 caracteres
Aplicando la magia negra de boothby :
No estoy realmente seguro si entiendo cómo, o eso , funciona.
Uso:dc, 36 caracteres
Mi propia creación; un enfoque algo más tradicional, incluso aunque tuve que discutir un poco con el lenguaje para superar la falta de una
else
parte en lasif
declaraciones:Internamente produce todos los números de la secuencia y los almacena en la pila, luego
1
muestra el final y muestra la altura de la pila.fuente
2<x
ay deshacerse dek
. En caso de que quiera recuperar un byte después de cuatro años. : Dbrainfuck ,
5956 bytesPruébalo en línea! (Ligeramente modificado para facilitar su uso)
Entrada y salida como códigos de caracteres. Esto es más útil con celdas de tamaño arbitrario, pero aún puede funcionar con valores pequeños en tamaños de celda limitados.
Cómo funciona
fuente
Hexagonía ,
4844 bytesPruébalo en línea!
Expandido:
Tenga en cuenta que esto falla1
por uhh ... razones . Honestamente, ya no estoy seguro de cómo funciona esto. Todo lo que sé es que el código para números impares se ejecuta al revés para números pares. ¿De alguna manera?La nueva versión es mucho más limpia que la anterior, pero tiene algunas direcciones más en comparación y también termina en un error de división por cero. El único caso en el que no produce errores es cuando realmente se maneja
1
correctamente.fuente
If a number < 2 is input ... output does not matter.
: o)C,
7069 caracteresMuy simple, sin trucos.
Lee la entrada de stdin.
fuente
Q, 46
fuente
(#)1_(1<){(1+3*x;x%2)0=x mod 2}\
Ruby 1.9, 49 caracteres
Rubyfied Valentin CLEMENT responde a Python , utilizando la sintaxis lambda stabby. Se dividió en una declaración para mayor ilegibilidad.
Algunos gastos generales porque Ruby, a diferencia de Python, no está contento con mezclar números con booleanos.
fuente
C ++ (
5148)Esta es una función recursiva que hace esto; La lectura de entrada viene por separado.
Estoy seguro de que puedo hacer algún tipo de "y / o" truco con las
== 0
cosas, pero no tengo idea de cómo.fuente
==0
e intercambiar los lados del condicionaln==1
porque especifiqué en la pregunta que el número siempre es mayor que 1n==1
es el caso base de recursión. Ponern==2
allí no mejoraría la puntuación.return~-n?
e intercambiar los lados condicionalesn==1
==n<2
.~ - ~! (Sin comentarios) -
7153Obviamente, este lenguaje no es el mejor para el golf, ya que carece de una gran cantidad de funcionalidades nativas, pero esa es su belleza.
Primero, configure
'''
su entrada. La función''
se puede llamar entonces%
como entrada y devolverá la respuesta, así:'''=~~~~~:''&%:
Esto devolverá
~~~~~
. Realmente funciona paran==1
(se repite para siempren==0
).Como siempre con este lenguaje, no probado.
fuente
JavaScript (ES6) - 29 caracteres
Crea una función
f
que acepta un único argumento y devuelve el número de iteraciones.JavaScript: 31 caracteres
Asume que la entrada está en la variable
n
y crea una variablec
que contiene el número de iteraciones (y también se enviarác
a la consola como su último comando).fuente
Perl 6, 40 bytes
Método de función recursiva, según Valentin CLEMENT y daniero : 40 caracteres
Método de lista perezosa: 32 caracteres
fuente
> <>,
27 2623 bytesAl igual que las otras respuestas> <>, esto construye la secuencia en la pila. Una vez que la secuencia alcanza 2, el tamaño de la pila es el número de pasos dados.
Gracias a @Hohmannfan, ahorró 3 bytes mediante un método muy inteligente de calcular el siguiente valor directamente. La fórmula utilizada para calcular el siguiente valor en la secuencia es:
La fracción asigna números pares a 0.5 y números impares a 3. Multiplicar por
n
y sumarn%2
completa el cálculo, ¡no es necesario elegir el siguiente valor!Edición 2: Aquí está la versión pre @ Hohmannfan:
El truco aquí es que ambos
3n+1
yn/2
se calculan en cada paso de la secuencia, y el que se eliminará de la secuencia se elige después. Esto significa que el código no necesita bifurcarse hasta alcanzar 1, y el cálculo de la secuencia puede vivir en una línea de código.Editar: Golfed otro personaje después de darse cuenta de que el único entero positivo que puede conducir a 1 es 2. Como la salida del programa no importa para la entrada <2, la generación de secuencia puede terminar cuando se alcanza 2, dejando el tamaño de la pila siendo el número exacto de pasos requeridos.
Versión anterior:
fuente
\::2%:@5*1+2,*+:2=?