Antecedentes
La secuencia 1-2-3-Tribonacci
Imagine por un segundo que podría hacer una secuencia de Fibonacci reemplazando la fórmula de iteración estándar con lo siguiente:
Básicamente, en lugar de sumar los dos últimos para obtener el siguiente, sumas los últimos tres. Esta es la base de la secuencia 1-2-3-Tribonacci.
Criterio de Brown
El Criterio de Brown establece que puede representar cualquier valor entero como una suma de miembros de una secuencia siempre que:
Para todos los
n
mayores de 1,
¿Qué significa esto para el desafío?
Puede describir cualquier número entero positivo como una suma de miembros de la secuencia 1-2-3-Tribonacci formada por las siguientes condiciones iniciales:
Esto se conoce como, para cada valor en esta secuencia, la proporción entre términos nunca es mayor que 2 (la proporción promedia aproximadamente 1.839).
Cómo escribir en este sistema de representación numérica
Digamos que usa una representación little-endian. Alinee a los miembros de la secuencia de la siguiente manera:
1 2 3 6 11 20 37 68
Luego, toma su número para representarlo (para nuestras pruebas, digamos que es 63
) y encuentra los valores de los 1-2-3-Tribonacci dados que suman 63 (¡usando primero los valores más grandes!) . Si el número es parte de la suma, ponga un 1 debajo, 0 si no.
1 2 3 6 11 20 37 68
0 0 0 1 0 1 1 0
Puede hacer esto para cualquier número entero dado, ¡primero verifique que use los valores más grandes debajo de su entrada dada!
Definición (finalmente)
Escriba un programa o función que haga lo siguiente, dada una entrada entera positiva n
(escrita en cualquier base estándar) entre 1 y el valor máximo de su idioma:
- Convierta el valor en la representación numérica definida de 1-2-3-Tribonacci.
- Usando esta representación de tipo binario, y léelo como si fuera binario. Esto significa que los dígitos permanecen iguales, pero lo que significan cambia.
- Tome este número binario y conviértalo en la base del número original.
- Envía o devuelve este nuevo número.
Sin embargo, mientras la salida sea válida, no necesita seguir estos pasos. Si mágicamente encuentra alguna fórmula que es más corta (y matemáticamente equivalente), siéntase libre de usarla.
Ejemplos
Deje que la función f
sea la función descrita por la definición y []
represente los pasos tomados (como little-endian, aunque no debería importar) (no es necesario que siga este proceso, este es solo el proceso descrito):
>>> f(1)
[1]
[1]
[1]
1
>>> f(5)
[5]
[0, 1, 1]
[6]
6
>>> f(63)
[63]
[0, 0, 0, 1, 0, 1, 1]
[104]
104
fuente
Respuestas:
Javascript
117111bytesGracias a @theonlygusti por ayudar al golf con 5 bytes
Cómo funciona
Primero, la función genera todos los números de tribonacci hasta que encuentra uno mayor que la entrada
A continuación, realiza búsquedas inversas en la lista de números. Si un número es menor que la entrada, agrega 2 ^ (índice de ese número) al valor de retorno y reduce la entrada en ese número.
Finalmente devuelve el resultado.
Pruébalo en línea
fuente
a[++i]<x
dentro de la condición for para guardar un byte?x>0
conx
. Guardar otros 2 bytes.Python 2 ,
110102 bytes-3 bytes gracias a Rod (buen truco para lanzar boolean
i
a un int+i
para que la repr`+i`
funcione)Pruébalo en línea!
fuente
'01'[i]
con`+i`
i
es un booleano, no un int. Editar - Ohhh+i
, ordenado.JavaScript (ES6),
9793 bytesAquí, estamos usando
reduce()
una función recursiva. Suponemos que la salida es de 31 bits (que es la mayor cantidad sin signo con la que JS puede trabajar fácilmente para operaciones bit a bit de todos modos).En cuanto al rendimiento, esto claramente no es muy eficiente.
Para los curiosos:
F()
N + 1reduce()
iteraciones vs N iteraciones converge rápidamente hacia la constante de Tribonacci (≈ 1.83929). Por lo tanto, cada bit adicional en la salida cuesta aproximadamente el doble de tiempo que el anterior.F()
función se llama un buen 124 millones de veces.Prueba
Nota: Esto puede tardar 1 o 2 segundos en completarse.
Mostrar fragmento de código
fuente
Mathematica,
7874 bytesLinearRecurrence[{1,1,1},{1,2,3},#]
genera una lista, de longitud igual a la entrada, de los números tribonacci 1-2-3. (El{1,1,1}
representa la suma de los tres términos anteriores, mientras que{1,2,3}
son los valores iniciales.) Luego#~NumberDecompose~
encuentra la forma más codiciosa de escribir la entrada como una suma de elementos de la lista (esta es la misma función que descompondría una cantidad monetaria en múltiplos de las monedas disponibles, por ejemplo). Finalmente,Fold[#+##&,...]
convierte la lista binaria resultante en un entero (base-10).Presentación previa:
Como suele ser el caso (aunque no arriba), esta versión de golf es súper lenta en entradas mayores de 20 o más, porque genera (con recursión no optimizada) una lista de tribus cuya longitud es la entrada; reemplazar la final
#
por un límite más razonable comoRound[2Log@#+1]
resultados en un rendimiento mucho mejor.fuente
123Tribonacci[]
construcción?Haskell, 95 bytes
Ejemplo de uso:
f 63
->104
. Pruébalo en línea! .Cómo funciona:
!
construye la secuencia 1-2-3-Tribonacci. Dado1
,2
y3
como los parámetros de inicio, tomamos los primerosn
elementos de la secuencia. Luego veces a partir de la función de la derecha#
, que resta el siguiente elementoe
den
y establece el bit en el valor de retornor
sie
se necesita o deja que el desarmado bits. Establecer el bit es duplicarr
y agregar1
, dejar que se desactive es simplemente duplicar.fuente
Jalea , 31 bytes
Pruébalo en línea!
Estoy casi seguro de que hay una manera MUCHO más corta de lograr esto en Jelly.
¿Cómo?
fuente
Perl 6 ,
9391 bytes-2 bytes gracias a b2gills
Cómo funciona
Primero, genera la secuencia 1-2-3-Tribonacci hasta el primer elemento más grande que la entrada:
En base a eso, encuentra el subconjunto de la secuencia que se suma a la entrada:
Basado en eso, construye una lista de booleanos que especifica si cada elemento de la secuencia es parte de la suma:
Y finalmente interpreta esa lista de valores True = 1, False = 0 como base 2 y la devuelve como un número (base 10):
fuente
*>$^n
y.sum==$n
. Además, el espacio no es necesario entremy
y@f
JavaScript (ES6),
6160 bytesCalcula los números 1-2-3-Tribonacci hasta que alcanza el número original, luego, a medida que la recursión se desenrolla, trata de restar cada uno por turno, duplicando el resultado a medida que avanza.
Editar: guardado 1 byte gracias a @Arnauld.
fuente
n=>(g=(x,y,z)=>(n>x&&g(y,z,x+y+z)*2)+!(n<x||![n-=x]))(1,2,3)
guardar un byte?n<x||
pero eso![]
es genial.Lote,
151148145 bytesPuerto de mi respuesta de JavaScript. Editar: guardé 3 bytes al pasar mis argumentos de subrutina en orden inverso y otros 3 bytes al usar
@
s individuales en cada línea en lugar de@echo off
.fuente
Jalea ,
191817 bytesPruébalo en línea!
Antecedentes
En lugar de intentar convertir un número entero a 1,2,3-Tribonacci base, luego de binario a entero, haremos lo contrario: convertir enteros a binario, luego de 1,2,3-Trionacci base a entero, y regresar el más alto que coincide con la entrada. Esto se logra fácilmente.
Ejemplificaremos el proceso para la entrada 63 , en particular el paso donde se prueba 104 . En binario, del dígito más significativo al menos significativo, 104 es igual a
donde la segunda fila representa los valores posicionales de esos dígitos.
Podemos extender la secuencia 1,2,3-Tribonacci a la derecha, observando que los dígitos agregados cumplen con la misma fórmula recursiva. Para tres dígitos más, esto da
Ahora, para calcular el valor del número base 1,2,3-Tribonacci, podemos hacer uso de la fórmula recursiva. Dado que cada número es la suma de los tres números a su derecha (en la tabla anterior), podemos eliminar el primer dígito y agregarlo a los primeros tres dígitos de la matriz restante. Después de 7 pasos, que es igual al número de dígitos binarios de 104 , rara vez nos quedamos con solo tres dígitos.
Ahora, dado que el primer y el último dígito restante tienen valor posicional 0 , el resultado es el dígito del medio, es decir, 63 .
Cómo funciona
fuente
Gelatina ( tenedor ),
1716 bytesAhorré 1 byte gracias a @Dennis que lo jugó sin siquiera ejecutarlo.
Esto se basa en una bifurcación de Jelly donde estoy decepcionantemente trabajando en la implementación de un átomo de solución de Frobenius eficiente. Para aquellos que estén interesados, me gustaría hacer coincidir la velocidad de Mathematica
FrobeniusSolve
y afortunadamente hay una explicación de su método en el documento "Haciendo el cambio y encontrando repfigits: equilibrando una mochila" de Daniel Lichtblau.Explicación
fuente
ḣ3S;µ¡¶3RṚdzæFṪḄ
? No tengo tu horquilla instalada, así que no puedo probar.³
hace referencia al primer argumento.jelly.py
tenía otras cosas después de la última confirmación.dc ,
110102 bytesPues bien, parece que las grandes mentes no piensan igual. Aparentemente, el algoritmo que se me ocurrió para sortear las limitaciones
dc
es el mismo que se usó en la respuesta de @ LliwTelrac. Interesante.Pruébalo en línea!
fuente
Python 2 , 93 bytes
Este es un puerto de mi respuesta Jelly .
Pruébalo en línea!
fuente
bash + utilidades BSD (OS X, etc.), 53 bytes
bash + utilidades GNU (también funciona bajo BSD), 59 bytes
La entrada y la salida en los dos anteriores están en binario.
Pruebe la versión de GNU en TIO. (El ejemplo vinculado a muestra la entrada de 111111, que es 63 en binario, y la salida de 1101000, que es 104 en binario).
No creo que TIO ofrezca una opción de BSD, pero si tiene una Mac disponible, puede probar ambas. (El programa de 59 bytes es mucho más rápido que el programa de 53 bytes).
Desafortunadamente,
seq
no se puede colocar simplemente en la solución BSD en lugar dejot
, ya que el formato de salidaseq
es diferente para salidas superiores a 999999. (Esto comienza a ser un problema para las entradas alrededor de 32, ya que 32 ^ 4> 1000000).Puede reemplazar el
jot
anterior conseq -f%.f
para que esto funcione con las utilidades GNU, pero para los mismos 59 bytes, puede usar la solución GNU anterior, que es mucho más rápida.fuente