El teorema de Zeckendorf muestra que cada entero positivo puede representarse de manera única como una suma de números de Fibonacci no adyacentes. En este desafío, debes calcular la suma de dos números en la representación de Zeckendorf.
Sea F n es el n -ésimo número de Fibonacci, donde
F 1 = 1,
F 2 = 2 y
para todo k > 2, F k = F k - 1 + F k - 2 .
La representación Z ( n ) de Zeckendorf de un número entero no negativo n es un conjunto de números enteros positivos tales que
n = Σ i ∈ Z ( n ) F i y
∀ i ∈ Z ( n ) i + 1 ∉ Z ( n ).
(en prosa: la representación de Zeckendorf de un número n es un conjunto de enteros positivos de tal manera que los números de Fibonacci para estos índices suman n y no hay dos enteros adyacentes que formen parte de ese conjunto)
Notablemente, la representación de Zeckendorf es única. Estos son algunos ejemplos de representaciones de Zeckendorf:
Z (0) = ∅ (el conjunto vacío)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} no es la representación de Zeckendorf de 3)
Z (10) = {5, 2}
Z (100) = {3, 5, 10}
En este desafío, las representaciones de Zeckendorf se codifican como conjuntos de bits donde el bit menos significativo representa si 1
es parte del conjunto, etc. Puede suponer que las representaciones de Zeckendorf de entrada y salida encajan en 31 bits.
Su tarea es calcular Z ( n + m ) dados Z ( n ) y Z ( m ). La solución con la longitud más corta en octetos gana.
Puede encontrar una implementación de referencia escrita en ANSI C aquí . También se puede usar para generar representaciones de Zeckendorf o calcular un número a partir de su representación de Zeckendorf.
Aquí hay algunos pares de entrada y salida de muestra, donde las dos primeras columnas contienen la entrada y la tercera columna contiene la salida:
73865 9077257 9478805
139808 287648018 287965250
34 279004309 279004425
139940 68437025 69241105
272794768 1051152 273846948
16405 78284865 83888256
9576577 4718601 19013770
269128740 591914 270574722
8410276 2768969 11184785
16384 340 16724
Respuestas:
K (ngn / k) ,
45 43 4241 bytesPruébalo en línea!
Algoritmo de @ Bubbler
{
}
funcionar con argumentox
64(
)/0
hacer 64 veces, usando 0 como valor inicial:1,
anteponer 1+':
agregue cada prior (deje el primer elemento intacto)F:
asignar aF
para "secuencia de fibonacci"|
contrarrestar(
..){y!x}\
.. comenzando con el valor de la izquierda, calcule los residuos acumulativos (de izquierda a derecha) para la lista de la derecha. el valor de la izquierda es la suma simple de las entradas sin representación de zeckendorf:2\x
binario codificar las entradas. esta será una matriz nbits-by-2|
contrarrestar+/'
suma cada&
donde estan los 1s - lista de índices. si hay 2, el índice correspondiente se repite dos veces.F@
matriz de indexación enF
+/
suma<':
menos que cada anterior (el primero del resultado siempre será falsey)2/
decodificación binariafuente
CJam,
7674706359 bytesPruébelo en línea en el intérprete de CJam o verifique todos los casos de prueba a la vez .
Idea
Comenzamos definiendo una variación menor de la secuencia en la pregunta:
De esta manera, el bit 0 (LSB) de la entrada o salida de las matrices de bits corresponde al número de Fibonacci G 0 y, en general, el bit k a G k .
Ahora, reemplazamos cada bit establecido en Z (n) y Z (m) por el índice que codifica.
Por ejemplo, la entrada 532 10 = 1000010100 2 se transforma en [2 4 9] .
Esto produce dos matrices de enteros, que podemos concatenar para formar uno solo.
Por ejemplo, si n = m = 100 , el resultado es A: = [2 4 9 2 4 9] .
Si reemplazamos cada k en A por G k y sumamos los resultados, obtenemos n + m = 200 , por lo que A es una forma de descomponer 200 en números de Fibonacci, pero ciertamente no es la del teorema de Zeckendorf.
Teniendo en cuenta que G k + G k + 1 = G k + 2 y G k + G k = G k + G k-1 + G k-2 = G k + 1 + G k-2 , podemos sustituirlos consecutivamente e índices duplicados por otros (a saber, (k, k + 1) por k + 2 y (k, k) por (k + 1, k - 2) ), repitiendo esas sustituciones una y otra vez hasta alcanzar la representación de Zeckendorf. 1
Debe tomarse un caso especial para los índices negativos resultantes. Como G -2 = 0 , el índice -2 puede simplemente ignorarse. Además, G -1 = 0 = G 0 , por lo que cualquier -1 resultante debe ser reemplazado por 0 .
Para nuestro ejemplo A , obtenemos las siguientes representaciones (ordenadas), siendo la última la representación de Zeckendorf.
[2 2 4 4 9 9] → [0 3 4 4 9 9] → [0 5 4 9 9] → [0 6 9 9] → [0 6 7 10] → [0 8 10]
Finalmente, volvemos de la matriz de enteros a la matriz de bits.
Código
1 La implementación intenta sustituir 32 veces y no verifica si se ha alcanzado la representación de Zeckendorf. No tengo una prueba formal de que esto sea suficiente, pero he probado todas las sumas posibles de representaciones de 15 bits (cuyas representaciones requieren hasta 17 bits) y 6 repeticiones fueron suficientes para todas ellas. En cualquier caso, es posible aumentar el número de repeticiones a 99 sin aumentar el recuento de bytes, pero perjudicaría el rendimiento.
fuente
APL (Dyalog Extended) , 39 bytes
Pruébalo en línea!
Cambió a un programa completo tomando un argumento de longitud 2, y también cambió el generador de Fibonacci. Gracias a @ngn por muchas ideas.
Utiliza
⎕IO←0
para que⍳2
evalúe a0 1
.Generador de Fibonacci (nuevo)
Tenga en cuenta que los dos últimos números son inexactos, pero no cambia la salida del programa.
Zeckendorf a llanura (parcial)
APL (Dyalog Extended) , 47 bytes
Pruébalo en línea!
Cambió la Parte 1 de la respuesta anterior para reutilizar los números de Fibonacci. Además, suelte el duplicado 1 para guardar algunos bytes en otros lugares.
Parte 1 (nueva)
APL (Dyalog Extended) , 52 bytes
Pruébalo en línea!
Cómo funciona
No es necesario un algoritmo sofisticado para hacer adiciones en Zeckendorf porque APL no es conocido por su funcionamiento en elementos individuales en una matriz. En cambio, seguí adelante para convertir las dos entradas de Zeckendorf a enteros simples, agregarlos y volver a convertirlos.
Parte 1: Zeckendorf a entero simple
Parte 2: Agregar dos enteros simples
Parte 3: Convertir la suma de nuevo a Zeckendorf
"Puede suponer que las representaciones de Zeckendorf de entrada y salida encajan en 31 bits" fue bastante útil.
El generador de Fibonacci
Esto se deduce de la propiedad de los números de Fibonacci: si Fibonacci se define como
entonces
Fibonacci a Zeckendorf dígitos
fuente
Haskell, 325
396bytesEDITAR: nueva versión:
z
hace el trabajo.fuente
=
están, por lo que los padres no son necesarios , y así sucesivamente, y tenga en cuenta que se:
asocia a la derecha y puede cortar algunos allí. Pero, de todos modos, ¡felicidades! Se ve muy complicado. ¡No puedo esperar a descubrir cómo funciona esto!ES6, 130 bytes
Originalmente traté de calcular la suma en el lugar (de manera efectiva a lo largo de las líneas de la implementación de CJam) pero seguí quedando sin temporarios, así que simplemente convertí los números a números enteros reales.
(Sí, probablemente pueda guardar un byte usando eval.)
fuente
Ruby ,
85 7365 bytesPruébalo en línea!
¿Cómo?
Primero obtenga un límite superior para la suma codificada: (a + b) * 2 está bien.
Ahora filtre todos los números no zeckendorf de (0..limit).
Tenemos una tabla de búsqueda, es cuesta abajo desde aquí.
fuente
Python 3, 207 bytes
Pruébalo en línea! (Verifique todos los casos de prueba)
Explicación
Este programa manipula directamente las traducciones binarias de las representaciones de Zeckendorf. La función
a(n,m)
realiza los cálculos principales ys(n)
es una función auxiliar que elimina los números adyacentes contenidos en la representación de Zeckendorf.Comencemos con la función
s(n)
(expandida para mayor claridad):Por ejemplo, el número 107 (
1101011
en binario, que representa 1 + 2 + 5 + 13 + 21 = 42), se somete al siguiente proceso:Pruébalo en línea! (s con salida detallada)
Aquí hay una versión ampliada de
a(n,m)
:Esta función convierte las dos representaciones de Zeckendorf en cuatro números binarios que son más fáciles de combinar. La línea (A) es el OR bit a bit de las dos representaciones binarias de Zeckendorf, que corresponden a una copia de cada número de Fibonacci en cualquier grupo. (B) y (C) son los bits Y de los dos números desplazados a la derecha 1 y 2 veces, respectivamente. Sabemos que cuando se suman los números de Fibonacci correspondientes para (B) y (C), serán equivalentes al AND a nivel de bits de nuestro
n
ym
porque F (n) = F (n-1) + F (n-2) .Por ejemplo, supongamos que tenemos los números binarios n = 101001 (correspondientes a 1 + 5 + 13) ym = 110110 (2 + 3 + 8 + 13). Entonces tendremos (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13), que se convierte a 1010100 (3 + 8 + 21) por nuestra función
s
, (B) = 10000 (8), y ( C) = 1000 (5). Podemos verificar que (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45. Este proceso se repite con ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5), etc.¡La única dificultad con este sistema es que no funciona para los números 1 y 2 de Fibonacci, ya que no obedecen la propiedad
F(n)=F(n-1)+F(n-2)
(son los dos números más bajos)! Debido a eso, cuando 1 o 2 está contenido en ambosn
ym
, se eliminan de A, B y C, su suma se coloca en D debajo de la propiedad que 1 + 1 = 2 y 2 + 2 = 1 + 3. Por ejemplo, si agregamos 1 + 3 (101) + 1 + 3 + 5 (1101), obtenemos:(A): 3 + 5 (1100) = 8 (10000)
(B): 2 (10)
(C): 1 (1)
(D): 2 (10)
Observe que los 3 y 5 se colocaron en A, el duplicado 3 se dividió en 2 + 1 en B y C, y los duplicados 1 se eliminaron de A, B y C, se agregaron y se pusieron en D. De manera similar, si sumamos 2 + 3 (110) + 2 + 3 + 5 (1110), obtenemos:
(A): 3 + 5 (1100) = 8 (10000)
(B): 2 (10)
(C): 1 (1)
(D): 1 + 3 (101)
Pruébalo en línea! (a con salida detallada)
fuente
Wolfram Language (Mathematica) , 218 bytes
Pruébalo en línea!
Simplemente coincidencia de patrones.
Sin golf:
fuente