O teorema de Zeckendorf mostra que todo número inteiro positivo pode ser representado exclusivamente como uma soma de números de Fibonacci não adjacentes. Neste desafio, você deve calcular a soma de dois números na representação de Zeckendorf.
Seja F n o n- ésimo número de Fibonacci onde
F 1 = 1,
F 2 = 2 e
para todos k > 2, F k = F k - 1 + F k - 2 .
A representação Zeckendorf Z ( n ) de um número inteiro não negativo n é um conjunto de números inteiros positivos, de modo que
n = Σ i ∈ Z ( n ) F i e
∀ i ∈ Z ( n ) i + 1 ∉ Z ( n ).
(em prosa: a representação de Zeckendorf de um número n é um conjunto de números inteiros positivos, de modo que os números de Fibonacci para esses índices somam n e nenhum número inteiro adjacente faça parte desse conjunto)
Notavelmente, a representação de Zeckendorf é única. Aqui estão alguns exemplos para representações de Zeckendorf:
Z (0) = ∅ (o conjunto vazio)
Z (1) = {1}
Z (2) = {2}
Z (3) = {3} ({1, 2} não é a representação de Zeckendorf de 3)
Z (10) = {5, 2}
Z (100) = {3, 5, 10}
Nesse desafio, as representações de Zeckendorf são codificadas como conjuntos de bits, onde o bit menos significativo representa se 1
faz parte do conjunto, etc. Você pode assumir que as representações de entrada e saída de Zeckendorf se encaixam em 31 bits.
Sua tarefa é calcular Z ( n + m ) dados Z ( n ) e Z ( m ). A solução com o menor comprimento em octetos vence.
Você pode encontrar uma implementação de referência escrita em ANSI C aqui . Também pode ser usado para gerar representações do Zeckendorf ou calcular um número a partir da representação do Zeckendorf.
Aqui estão alguns pares de amostra de entrada e saída, em que as duas primeiras colunas contêm a entrada e a terceira coluna contém a saída:
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
Respostas:
K (ngn / k) ,
45 43 4241 bytesExperimente online!
@ Algoritmo de Bubbler
{
}
função com argumentox
64(
)/0
faça 64 vezes, usando 0 como valor inicial:1,
anexar 1+':
adicione cada anterior (deixe o primeiro elemento intacto)F:
atribuir aF
"sequência de fibonacci"|
marcha ré(
..){y!x}\
.. começando com o valor à esquerda, calcule os restos cumulativos (da esquerda para a direita) para a lista à direita. o valor à esquerda é a soma simples das entradas sem representação zeckendorf:2\x
binário codifica as entradas. esta será uma matriz de nbits por 2|
marcha ré+/'
somar cada&
onde estão os 1s? - lista de índices. se houver 2s, o índice correspondente será repetido duas vezes.F@
indexação de matriz emF
+/
soma<':
menos que cada anterior (o primeiro do resultado será sempre falsey)2/
decodificação bináriafonte
CJam,
7674706359 bytesExperimente on-line no intérprete CJam ou verifique todos os casos de teste de uma só vez .
Idéia
Começamos definindo uma variação menor da sequência na pergunta:
Dessa forma, o bit 0 (LSB) da matriz de bits entrada ou saída corresponde ao número de Fibonacci G 0 e, em geral, o bit k a G k .
Agora, substituímos cada bit definido em Z (n) e Z (m) pelo índice que ele codifica.
Por exemplo, a entrada 532 10 = 1000010100 2 é transformada em [2 4 9] .
Isso produz duas matrizes de números inteiros, que podemos concatenar para formar uma única.
Por exemplo, se n = m = 100 , o resultado é A: = [2 4 9 2 4 9] .
Se substituirmos cada k em A por G k e somarmos os resultados, obteremos n + m = 200 ; portanto, A é uma maneira de decompor 200 em números de Fibonacci, mas certamente não o do teorema de Zeckendorf.
Tendo em mente que G k + G k + 1 = G k + 2 e G k + G k = G k + G k-1 + G k-2 = G k + 1 + G k-2 , podemos substituir consecutivamente e índices duplicados por outros (a saber, (k, k + 1) por k + 2 e (k, k) por (k + 1, k - 2) ), repetindo essas substituições repetidamente até que a representação de Zeckendorf seja alcançada. 1
É necessário um caso especial para os índices negativos resultantes. Como G -2 = 0 , o índice -2 pode ser simplesmente ignorado. Além disso, G -1 = 0 = G 0 , portanto, qualquer -1 resultante deve ser substituído por 0 .
Para o nosso exemplo A , obtemos as seguintes representações (classificadas), sendo a última a representação 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, convertemos de volta da matriz de números inteiros para a matriz de bits.
Código
1 A implementação tenta substituir 32 vezes e não verifica se a representação de Zeckendorf foi realmente alcançada. Não tenho uma prova formal de que isso seja suficiente, mas testei todas as somas possíveis de representações de 15 bits (cujas representações de somas exigem até 17 bits) e 6 repetições foram suficientes para todas elas. Em qualquer caso, é possível aumentar o número de repetições para 99 sem aumentar a contagem de bytes, mas isso prejudicaria o desempenho.
fonte
APL (Dyalog Extended) , 39 bytes
Experimente online!
Mudou para um programa completo, tendo um argumento de comprimento 2, e também alterou o gerador de Fibonacci. Obrigado a @ngn por muitas idéias.
Usa
⎕IO←0
para que seja⍳2
avaliado como0 1
.Gerador de Fibonacci (novo)
Observe que os dois últimos números são imprecisos, mas isso não altera a saída do programa.
Zeckendorf para planície (parcial)
APL (Dyalog Extended) , 47 bytes
Experimente online!
A parte 1 da resposta anterior foi alterada para reutilizar os números de Fibonacci. Solte também o duplicado 1 para salvar alguns bytes em outros lugares.
Parte 1 (nova)
APL (Dyalog Extended) , 52 bytes
Experimente online!
Como funciona
Nenhum algoritmo sofisticado para fazer adição no Zeckendorf porque o APL não é conhecido por operar em elementos individuais em uma matriz. Em vez disso, fui em frente para converter as duas entradas do Zeckendorf em números inteiros simples, adicioná-las e convertê-las novamente.
Parte 1: Zeckendorf para inteiro simples
Parte 2: adicione dois inteiros simples
Parte 3: Converter a soma novamente em Zeckendorf
"Você pode assumir que as representações de entrada e saída de Zeckendorf cabem em 31 bits" foi bastante útil.
O gerador de Fibonacci
Isso decorre da propriedade dos números de Fibonacci: se Fibonacci for definido como
então
Dígitos de Fibonacci em Zeckendorf
fonte
Haskell, 325
396bytesEDIT: nova versão:
z
faz o trabalho.fonte
=
estão, para que os pais não sejam necessários e assim por diante, e observe que os:
associados à direita podem ser cortados lá. Mas, de qualquer forma, parabéns! Parece muito complicado. Mal posso esperar para descobrir como isso funciona!ES6, 130 bytes
Originalmente, tentei calcular a soma no local (efetivamente ao longo das linhas da implementação do CJam), mas continuava ficando sem temporários; portanto, apenas converti os números para números anteriores reais.
(Sim, provavelmente posso salvar um byte usando eval.)
fonte
Ruby ,
85 7365 bytesExperimente online!
Como?
Primeiro, obtenha um limite superior para a soma codificada: (a + b) * 2 está ok.
Agora filtre todos os números não zeckendorf de (0..limit).
Temos uma mesa de pesquisa, é ladeira abaixo daqui.
fonte
Python 3, 207 bytes
Experimente Online! (Verifique todos os casos de teste)
Explicação
Este programa manipula diretamente as traduções binárias das representações de Zeckendorf. A função
a(n,m)
executa os cálculos principais es(n)
é uma função auxiliar que se livra dos números adjacentes contidos na representação Zeckendorf.Vamos começar com a função
s(n)
(expandida para maior clareza):Por exemplo, o número 107 (
1101011
em binário, representando 1 + 2 + 5 + 13 + 21 = 42), passa pelo seguinte processo:Experimente Online! (s com saída detalhada)
Aqui está uma versão expandida de
a(n,m)
:Esta função converte as duas representações de Zeckendorf em quatro números binários que são mais fáceis de combinar. A linha (A) é o OR bit a bit das duas representações binárias de Zeckendorf - elas correspondem a uma cópia de cada número de Fibonacci nos dois grupos. (B) e (C) são AND bit a bit dos dois números deslocados para a direita 1 e 2 vezes, respectivamente. Sabemos que quando os números correspondentes de Fibonacci para (B) e (C) são somados, eles serão equivalentes aos AND bit a bit do nosso
n
em
porque F (n) = F (n-1) + F (n-2) .Por exemplo, digamos que temos os números binários n = 101001 (correspondendo a 1 + 5 + 13) e m = 110110 (2 + 3 + 8 + 13). Então teremos (A) = 111111 (1 + 2 + 3 + 5 + 8 + 13), que é convertido em 1010100 (3 + 8 + 21) por nossa função
s
, (B) = 10000 (8) e ( C) = 1000 (5). Podemos verificar que (1 + 5 + 13) + (2 + 3 + 8 + 13) = (3 + 8 + 21) + (8) + (5) = 45. Esse processo se repete com ((3 + 8 + 21) + (8)) + (5) = ((3 + 8 + 21) + (5) + (3)) + (5), etc.A única dificuldade desse sistema é que ele não funciona para os números 1 e 2 de Fibonacci, pois eles não obedecem à propriedade
F(n)=F(n-1)+F(n-2)
(são os dois números mais baixos)! Por isso, sempre que 1 ou 2 está contido em ambosn
em
, eles são removidos de A, B e C, sua soma é colocada em D sob a propriedade que 1 + 1 = 2 e 2 + 2 = 1 + 3. Por exemplo, se adicionarmos 1 + 3 (101) + 1 + 3 + 5 (1101), obtemos:(A): 3 + 5 (1100) = 8 (10000)
(B): 2 (10)
(C): 1 (1)
(D): 2 (10)
Observe que os 3 e 5 foram colocados em A, o duplicado 3 foi dividido em 2 + 1 em B e C e os 1s duplicados foram removidos de A, B e C, somados e inseridos em D. Da mesma forma, se adicione 2 + 3 (110) + 2 + 3 + 5 (1110), obtemos:
(A): 3 + 5 (1100) = 8 (10000)
(B): 2 (10)
(C): 1 (1)
(D): 1 + 3 (101)
Experimente online! (a com saída detalhada)
fonte
Wolfram Language (Mathematica) , 218 bytes
Experimente online!
Simplesmente correspondência de padrões.
Ungolfed:
fonte