Defina la función f (n) para un entero positivo n de la siguiente manera:
- n / 2 , si n es par
- 3 * n + 1 , si n es impar
Si aplica repetidamente esta función a cualquier n mayor que 0, el resultado siempre parece converger a 1 (aunque todavía nadie ha podido probarlo). Esta propiedad se conoce como la conjetura de Collatz .
Defina el tiempo de detención de un número entero como el número de veces que debe pasarlo a través de la función Collatz f antes de que llegue a 1. Aquí están los tiempos de detención de los primeros 15 enteros:
1 0
2 1
3 7
4 2
5 5
6 8
7 16
8 3
9 19
10 6
11 14
12 9
13 9
14 17
15 17
Llamemos a cualquier conjunto de números con el mismo tiempo de detención que los primos de Collatz . Por ejemplo, 5 y 32 son primos de Collatz, con un tiempo de parada de 5.
Su tarea: escribir un programa o función que tome un número entero no negativo y genere el conjunto de primos de Collatz cuyo tiempo de detención es igual a ese número entero.
Entrada
Un entero S no negativo, dado a través de STDIN, ARGV o argumento de función.
Salida
Una lista de todos los números cuyo tiempo de detención es S, ordenados en orden ascendente . La lista puede ser generada por su programa, o devuelta o generada por su función. El formato de salida es flexible: está separado por espacios, por líneas nuevas o cualquier formato de lista estándar de su idioma, siempre que los números se puedan distinguir fácilmente entre sí.
Requisitos
Su envío debe dar resultados correctos para cualquier S ≤ 30. Debe finalizar en segundos o minutos, no en horas o días.
Ejemplos
0 -> 1
1 -> 2
5 -> 5, 32
9 -> 12, 13, 80, 84, 85, 512
15 -> 22, 23, 136, 138, 140, 141, 150, 151, 768, 832, 848, 852, 853, 904, 906, 908, 909, 5120, 5376, 5440, 5456, 5460, 5461, 32768
Aquí hay un resumen de la salida para S = 30 .
Esto es code-golf : el programa más corto en bytes gana. ¡Buena suerte!
Respuestas:
Pyth,
262421 bytesEste código se ejecuta instantáneamente por
S=30
. Pruébelo usted mismo: demostraciónGracias a @isaacg por guardar 5 bytes.
Explicación
Mi código comienza
1
y deshace la función Collatz. Mapea todos los númerosd
delS-1
paso a2*d
y(d-1)/3
. Sin embargo, el último no siempre es válido.fuente
-F
.- ... 1
suma alrededor de la reducción dentro de la reducción, no necesita que la reducción sea una.u
, ni el-F
exterior. Guarda 2 caracteres.q4%d6
es equivalente a!%hhd6
, pero 1 carácter más corto.Mathematica,
989289 bytesEsta solución resuelve
S = 30
inmediatamente:Esta es una función sin nombre que toma
S
como único parámetro y devuelve una lista de los primos de Collatz.El algoritmo es una búsqueda simple de amplitud. Los primos de Collatz para un dado
S
son todos los enteros a los que se puede llegar desde los primos de Collatz paraS-1
vía2*n
o números impares que se pueden alcanzar a través de(n-1)/3
. También debemos asegurarnos de que solo producimos aquellos enteros que se alcanzaron por primera vez después de losS
pasos, para que podamos hacer un seguimiento de todos los primos anterioresp
y eliminarlos del resultado. Como estamos haciendo eso de todos modos, podemos guardar algunos bytes calculando los pasos de todos los primos anteriores (no solo los deS-1
) para guardar algunos bytes (eso lo hace un poco más lento, pero no notablemente para lo requeridoS
).Aquí hay una versión un poco más legible:
fuente
Python 2,
8683757371 bytesLlama como
f(30)
.n = 30
Es casi instantáneo.(Gracias a @DLosc por la idea de recurrir
k
siendo un número en lugar de una lista de primos y unos pocos bytes. Gracias a @isaacg por dejarlo~-
).Esta variante es mucho más corta, pero desafortunadamente toma demasiado tiempo debido a la ramificación exponencial:
fuente
f=lambda d,n=1:d and sorted(sum((c(d-1,x)for x in[n*2]+[~-n/3][:n>4==n%6]),[]))or[n]
. Es menos eficiente con las llamadas a funciones, pero aún lo hacen = 30
en menos de un segundo.f=lambda n,k=1:sorted([k][n:]or(k>4==k%6and f(n-1,~-k/3)or[])+f(n-1,k*2))
~-
es innecesario porque estás usando la división de enteros.CJam,
2926 bytesEl crédito va a @isaacg por su idea de eliminar 1 después de cada iteración, lo que me ahorró dos bytes directamente y otro indirectamente.
Pruébelo en línea en el intérprete de CJam (debería terminar en menos de un segundo).
Cómo funciona
fuente
CJam, 35 bytes
Explicación próximamente. Esta es una versión mucho más rápida que el enfoque "bastante directo" (ver en el historial de edición).
Pruébelo en línea aquí para
N = 30
que se ejecuta en cuestión de segundos en la versión en línea y al instante en el compilador de Javafuente
It should finish in seconds or minutes, not hours or days.
S=15
no funciona.Java 8, 123
Cuando
x
tiene 30 años, el programa dura 15 minutos y 29 segundos.Expandido
fuente
javac 1.7.0_79
en Ubuntu me dio muchos errores de sintaxis.i > 1 && ++n <= x
(también puede caern++
) parece ser aún más rápido para solo 5 caracteres más ... unos 3 minutos para S = 30 para mí. Eso también se afeita con seguridad en menos de un minuto si lo.parallel()
Python 2, 118 bytes
Bueno, pensé que no alcanzaría el mejor puntaje de Python después de ver la solución de @ Sp3000. Pero parecía un pequeño problema divertido, así que de todos modos quería probar una solución independiente:
Lo mismo antes de eliminar espacios en blanco:
Esta es una implementación muy directa de una primera búsqueda amplia. En cada paso, tenemos el conjunto con el tiempo de detención
k
, y derivamos el conjunto con el tiempo de detenciónk + 1
agregando los posibles predecesores de cada valort
en el conjunto del pasok
:2 * t
siempre es un posible predecesor.t
puede escribirse como3 * u + 1
, dondeu
hay un número impar que no lo es1
, entonces tambiénu
es un predecesor.Tarda unos 0.02 segundos en ejecutarse
N = 30
en mi MacBook Pro.fuente
s.add(x)
es innecesario en un golf, ya que generalmente se puede hacer en sus|={x}
lugar. Además, usar en~-x
lugar de(x+1)
guardar en corchetes. Pero por lo demás, buen trabajo :)s.add()
porque se convierte en una tarea y ya no puedo ser parte de la expresión. Funciona para el primero. Losfor
bucles basados en contadores también son siempre bastante detallados. Pensé que podría acortarlo usando unwhile
bucle, pero resultó ser exactamente el mismo de la misma longitud.for
bucle, ya que no utiliza la entrada de ninguna otra manera, probablemente pueda hacerlo en suexec"..."*input()
lugar :)PHP 5.4+, 178 bytes
La función
Prueba y salida
S (30) se ejecuta en 0.24 segundos * , devuelve 732 elementos. Una pareja son
* Para ahorrar en bytes, tuve que agregar
ksort
yarray_keys
en cada paso. La única otra opción que tuve fue hacer una pequeña función de envoltura que llamac()
y luego llamaarray_keys
yksort
sobre el resultado una vez. Pero debido a que el tiempo aún es decentemente ágil, decidí tomar el rendimiento a bajo recuento de bytes. Sin la clasificación y el procesamiento adecuados, el tiempo es de 0.07 segundos en promedio para S (30).Si alguien tiene alguna manera inteligente de obtener el procesamiento adecuado solo una vez sin demasiados bytes adicionales, ¡hágamelo saber! (Almaceno mis números como teclas de matriz, de ahí el uso de
array_keys
yksort
)fuente
Lenguaje C
fuente
{}
botón para formatear su código, lo que he hecho por usted. Pero como dice Alex, agregue el nombre del idioma (C?) E intente jugarlo :) ¡Pero bienvenido!f
no se comporta correctamente. Cons=5
, obtengo un montón de resultados incorrectos.if (r == s)return true;
debería serreturn (r==s)
, yaf
que no devolverá ningún significado significativo cuando(r < s)
. Además, creo que se debe declarari
en laf
quelong
, desde que se desbordará con bastante rapidez para algunos valores.return (r==s);