Vamos definir a sequência de Fibonacci como
F(1) = 1
F(2) = 2
F(n) = F(n - 2) + F(n - 1)
Portanto, temos a sequência infinita 1,2,3,5,8,13,
... É sabido que qualquer número inteiro positivo pode ser escrito como uma soma de alguns números de Fibonacci. A única ressalva é que esse somatório pode não ser único. Sempre há pelo menos uma maneira de escrever um número como uma soma dos números de Fibonacci, mas pode haver muitos mais.
Seu desafio é escrever um programa completo que, usando stdin, receba um número inteiro positivo entre um e um milhão, inclusive, e emita usando stdout todas as somas possíveis de números de Fibonacci que somam a entrada. Em resumo, os números de Fibonacci não devem se repetir e isso inclui o número 1
. Em qualquer soma, se 1
estiver presente, deve estar presente apenas uma vez, porque na minha definição da sequência acima 1
aparece apenas uma vez. As somas com apenas um termo são válidas, portanto, se o número de entrada for um número de Fibonacci, o número em si será uma soma válida e deverá ser impresso. Se várias somas, entre duas somas, deve haver uma linha em branco para distinguir facilmente entre elas.
Aqui estão algumas amostras.
./myfib 1
1
Existe apenas uma dessas somas e tem apenas um termo, e é isso que é impresso.
./myfib 2
2
Observe aqui que 1+1
não é uma soma válida porque se 1
repete.
./myfib 3
1+2
3
Duas somas e ambas são impressas com uma linha em branco no meio.
./myfib 10
2+8
2+3+5
./myfib 100
3+8+89
1+2+8+89
3+8+34+55
1+2+3+5+89
1+2+8+34+55
3+8+13+21+55
1+2+3+5+34+55
1+2+8+13+21+55
1+2+3+5+13+21+55
Verdadeiro código de golfe. O código mais curto em qualquer idioma vence. Poste seu código com alguns casos de teste (além do que eu forneci acima). No caso de empate, eu escolho aquele com os votos mais altos depois de esperar pelo menos por duas semanas e provavelmente mais. Portanto, a comunidade sinta-se à vontade para votar em qualquer solução que desejar. A inteligência / beleza do código é muito mais importante do que quem publica primeiro.
Feliz codificação!
Respostas:
GolfScript, 54 caracteres
Teste on - line ou veja os exemplos:
fonte
Ruby,
118114 (saída da matriz) ou138134 (saída correta)Exemplo de execução:
Altere
gets
para$*[0]
se você deseja argumentos da linha de comando (>fibadd 100
), com um caractere +1.Com a saída correta:
Amostras de execuções:
Esse último (12804) levou apenas cerca de 3 segundos!
fonte
Mathematica,
8985 caracteresReduzido para 85 caracteres graças a David Carraher.
O Mathematica tem uma função interna
Fibonacci
, mas não quero usá-la.fonte
i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &]
i = Input[]; #~Row~"+" & /@ Select[If[# > i, Subsets@{##}, #0[# + #2, ##]] &[2, 1], Tr@# == i &] // Column
Pitão
206181 caracteresExemplo de execução:
fonte
while i<1000000:v+=[i];i,j=j,i+j
import itertools as z
remova as novas linhas após os dois pontos, insiray=input()
ax,y,v
linha e remova o espaço extra após aif
declaração final .Scala, 171
fonte
C #, 376 bytes
Ungolfed:
O método
B
retorna umIEnumerable
que representa todo o conjunto (infinito) de Fibonacci. O segundo método, dado um númeron
, analisa os primeirosn
números de Fibonacci (enorme exagero aqui), encontra todos os subconjuntos possíveis (o conjunto de potência) e depois filtra para os subconjuntos cuja soma é exatamenten
e depois imprime.fonte
APL (75)
Menos competitivo do que eu gostaria, principalmente por causa do formato de saída.
Resultado:
Explicação:
I←⎕
: ler entrada, armazenar emI
.⍳2
: começando com a lista1 2
,{⍵,+/¯2↑⍵}
: adicione a soma dos dois últimos elementos à lista,⍣{I<⊃⌽⍺}
: atéI
é menor que o último elemento da lista.F←
: armazenar emF
(estes são os números de fibonacci de1
aI
).N←⍴F
: armazene a quantidade de números de fibonacci emN
.↓⍉(N⍴2)⊤⍳2*N
: obtenha os números de1
para2^N
, como bits.S←/∘F¨
: use cada um deles como máscara de bitF
, armazeneS
.I=+/¨S
: para cada sub-listaS
, veja se a soma é igual aI
.S/⍨
: selecione estes deS
. (Agora, temos todas as listas de números de fibonacci que somamI
.){
...}¨
: para cada um destes:,'+',⍪⍵
: adicione um+
na frente de cada número,1↓
: retire a primeira+
,⎕TC[2]
: adicione uma nova linha extra,⎕←
: e saída.fonte
Haskell - 127
Após muitas iterações, acabei com o seguinte código:
Eu poderia ter salvo talvez um caractere trapaceando e adicionando um "0+" extra na frente de cada linha de saída.
Quero compartilhar outra versão (comprimento 143) que eu criei enquanto tentava jogar a solução anterior. Nunca abusei tanto de operadores e de tuplas antes:
Casos de teste, 256:
e 1000:
Alguns dados de eficiência, já que alguém tinha essas coisas:
fonte
05AB1E , 19 bytes (Não concorrente)
Experimente online!
Calcula todas as somas possíveis para qualquer dado
n
. Exemplo de saída para 1000:fonte