A palavra infinita de Fibonacci é uma sequência infinita específica de dígitos binários, calculada por concatenação repetida de palavras binárias finitas.
Vamos definir que uma sequência de palavras de Fibonacci-tipo (ou FTW sequência ) é qualquer sequência ⟨W n ⟩ que é formado como se segue.
Comece com duas matrizes arbitrárias de dígitos binários. Vamos chamar essas matrizes de W -1 e W 0 .
Para cada n> 0 , deixar W n ≔ W n-1 ∥ W N-2 , onde ∥ denota concatenação.
Uma conseqüência da definição recursiva é que W n é sempre um prefixo de W n + 1 e, portanto, de todos os W k, de modo que k> n . Num certo sentido, isso significa que a sequência ⟨W n ⟩ converge para uma palavra infinito.
Formalmente, seja W ∞ ser a matriz só infinito de tal modo que W n é um prefixo de W ∞ para todo n ≥ 0 .
Chamaremos qualquer palavra infinita formada pelo processo acima de FTW infinito .
Tarefa
Escreva um programa ou função que aceite duas palavras binárias W -1 e W 0 como entrada e imprima W ∞ , respeitando as seguintes regras adicionais:
Você pode aceitar as palavras em qualquer ordem; como duas matrizes, uma matriz de matrizes, duas cadeias, uma matriz de cadeias ou uma única cadeia com um delimitador de sua escolha.
Você pode imprimir os dígitos da palavra infinita sem um delimitador ou com um delimitador consistente entre cada par de dígitos adjacentes.
Para todos os efeitos, suponha que seu código nunca fique sem memória e que seus tipos de dados não sejam excedidos.
Em particular, isso significa que qualquer saída para STDOUT ou STDERR resultante de uma falha será ignorada.
Se eu executar seu código na minha máquina (Intel i7-3770, 16 GiB RAM, Fedora 21) por um minuto e canalizar sua saída
wc -c
, ele deverá imprimir pelo menos um milhão de dígitos de W ∞ para (W -1 , W 0 ) = (1, 0) .Aplicam-se as regras de código-golfe padrão .
Exemplo
Seja W -1 = 1 e W 0 = 0 .
Então W 1 = 01 , W 2 = 010 , W 3 = 01001 , W 4 = 01001010 … e W ∞ = 010010100100101001001010… .
Esta é a palavra infinita de Fibonacci.
Casos de teste
Todos os casos de teste contêm os primeiros 1.000 dígitos do FTW infinito.
Input: 1 0
Output: 0100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001
Input: 0 01
Output: 0100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001
Input: 11 000
Output: 0001100000011000110000001100000011000110000001100011000000110000001100011000000110000001100011000000110001100000011000000110001100000011000110000001100000011000110000001100000011000110000001100011000000110000001100011000000110000001100011000000110001100000011000000110001100000011000110000001100000011000110000001100000011000110000001100011000000110000001100011000000110001100000011000000110001100000011000000110001100000011000110000001100000011000110000001100000011000110000001100011000000110000001100011000000110001100000011000000110001100000011000000110001100000011000110000001100000011000110000001100000011000110000001100011000000110000001100011000000110001100000011000000110001100000011000000110001100000011000110000001100000011000110000001100011000000110000001100011000000110000001100011000000110001100000011000000110001100000011000000110001100000011000110000001100000011000110000001100011000000110000001100011000000110000001100011000000110001100000011000000110001100000011000110000001100000011
Input: 10 010
Output: 0101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001001010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010010100101001001010010100100101001001010010100100101001010010010100100101001010010010100100101001010010010100101001001010010010100101001001010010100100101001001010
Input: 101 110
Output: 1101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101101011101011101101011101101011101011101101011101011101101011101
Respostas:
Pitão, 8 bytes
Entrada no formulário
"W-1", "W0"
.Prova de conclusão:
Prova de correção:
Aqui está a série gerada internamente. É impresso em concatenação pelo programa.
Compare com o seguinte, impresso em concatenação, que é simplesmente a sequência adicionada à sequência anterior em cada etapa:
Queremos provar que são equivalentes.
Claramente, eles são os mesmos através dos primeiros passos. Vamos compará-los depois de um pouco:
Vemos que os pares de cordas são alternadamente das formas:
Onde aeb são seqüências arbitrárias em 0s e 1s. Vamos continuar a sequência um pouco, para provar que continua para sempre por indução:
2 etapas depois, é da forma correta.
2 etapas depois, é da forma correta.
Portanto, por indução, as cordas sempre correspondem uma vez concatenadas.
fonte
W0
mas em vez deW1
ser impressaW-1 || W0
, que é a ordem de concatenação "incorreta". Eu acho que isso funciona para ser equivalente, mas eu nãoHaskell, 15 bytes
A função infix
%
produz uma sequência infinita, que Haskell imprime para sempre porque Haskell é legal assim.A ideia recursiva é semelhante à solução do Zgarb . Escrevendo
f
para a função%
e+
para concatenação de cadeias, ele implementa:A seqüência de saída infinita começa com
w
, e o restante é o resultado das seqüências de Fibonacciw
ev+w
.Isso não tem problema em gerar um milhão de caracteres em um minuto.
fonte
Haskell, 31 bytes
Isso define uma função infix
#
que pega duas cadeias e retorna uma cadeia infinita. Uso:Se eu consultar o milionésimo elemento da sequência definida por "1" e "0", até o intérprete online imprimirá o resultado em menos de um segundo:
Explicação
Basicamente, sabemos disso
w#v == v#(v++w)
ew#v
começa comv
, e usamos esses fatos para definir o resultado. Como Haskell é preguiçoso, isso "magicamente" simplesmente funciona.fonte
Pip, 8 bytes
Ei, amarrado com Pyth!
Definição recursiva direta emprestada da resposta Haskell do xnor . Com espaços adicionados para maior clareza:
Cada programa em Pip é uma função implícita que leva os argumentos de linha de comando como seus argumentos (atribuídos às variáveis
a
atravése
) e imprime seu valor de retorno.O
é um operador que gera e retorna seu operando; portanto, a primeira coisa que acontece aqui é o segundo argumento (sem nova linha).Agora, a sintaxe inspirada no Lisp
(f x y)
no Pip é uma chamada de função, equivalente af(x,y)
linguagens do tipo C. Af
variável refere-se à função atual - neste caso, o programa de nível superior. Assim, o programa se chama recursivamente comb
ea.b
como novos argumentos.Fiquei agradavelmente surpreso ao descobrir que essa abordagem é bastante rápida:
Leva cerca de 30 segundos na minha máquina Ubuntu para que o programa atinja a profundidade máxima de recursão, momento em que foi impresso em algum lugar com mais de um bilhão de dígitos.
Essa solução iterativa é um pouco mais rápida e consome menos memória, ao custo de um byte:
fonte
CJam,
1211 bytesIsso leva as duas palavras em linhas separadas, na ordem oposta, por exemplo
dá
Explicação
A idéia é construir a palavra ingenuamente (lembrando a palavra atual e anexando a anterior) e enquanto fazemos isso, imprimimos o que acabamos de acrescentar (para não repetir o prefixo que já foi impresso) . Para evitar ter que lidar com o ponto de partida separadamente, partimos de uma palavra vazia, de modo que W 0 seja a primeira coisa que anexamos (e imprimimos).
fonte
PowerShell,
9776 bytesEditar - Umm, escrever
$e.substring($b.length)
depois de termos concatenado$a
e$b
juntos é equivalente a escrever apenas$a
... derp.Uau, detalhado. O PowerShell, por padrão, cuspirá uma nova linha toda vez que você produzir algo. Realmente a única maneira de contornar isso é com
write-host -n
(abreviação de-NoNewLine
), e que absolutamente mata o comprimento aqui.Essencialmente, este percorre a seqüência, construindo
$e
como o "atual" W n à medida que avançamos. No entanto, como queremos construir a palavra infinita em vez da sequência, aproveitamos nossas variáveis anteriores para imprimir o sufixo$a
preenchido em nosso loop anterior. Em seguida, configuramos nossas variáveis para a próxima rodada e repetimos o loop. Observe que isso espera que a entrada seja explicitamente delimitada como strings; caso contrário, o+
operador será usado para aritmética em vez de concatenação.Exemplo:
fonte
APL,
2418O uso da formulação do xnor permitiu raspar poucos caracteres.
Em uma máquina infinita em tempo infinito, na verdade, ele imprimia W três vezes - primeiro incrementalmente ao executar o loop e, em seguida, duas vezes como resultado de toda a expressão quando o
⍣≡
operador do ponto de fixação finalmente retorna.Não é muito rápido, mas rápido o suficiente. No GNU APL:
fonte
⍣≡
; Parece muito útil.Pure bash, 58
Fico sem memória antes de 1 minuto, mas já tenho muitos dígitos - depois de 10 segundos, tenho 100 milhões de dígitos:
fonte
Mathematica, 56 bytes
fonte
C, 76 (gcc)
Esta é uma impressora recursiva bastante simples, implementada como uma função aninhada (uma extensão GNU C não suportada pelo clang) para evitar ter que passar por
v
aí.p(n)
imprime W n-2 , onde W -1 e W 0 devem ser fornecidos emv[1]
ev[2]
. Isso inicialmente chamap(4)
para imprimir W 2 . Em seguida, faz um loop: chamap(3)
para imprimir W 1 , produzindo a saída completa W 2 W 1 , que é W 3 . Em seguida, ele chamap(4)
para imprimir W 2 , produzindo a saída completa W4 , etc. O desempenho é um pouco melhor do que minha resposta anterior: estou vendo 1875034112 valores em um minuto.C, 81 (toque)
Essa é uma abordagem completamente diferente da acima, que eu acho que vale a pena acompanhar, mesmo que a pontuação seja pior.
Isso tem todos os tipos de comportamento indefinido, principalmente por diversão. Ele funciona com o clang 3.6.2 no Linux e com o clang 3.5.2 no Cygwin para os casos de teste da pergunta, com ou sem opções especiais de linha de comando. Não quebra quando as otimizações estão ativadas.
Não funciona com outros compiladores.
Eu aceito as palavras como argumentos de linha de comando no formato de string.
Eu uso nova linha como delimitador consistente.
Eu acesso
s
fora dos limites. Isso certamente deve terminar com um segfault ou uma violação de acesso em algum momento.s
passa a ser colocado no final do segmento de dados, portanto, não deve prejudicar outras variáveis e fornecer saída incorreta antes desse segfault. Esperançosamente.Testando usando
{ ./program 1 0 | tr -d '\n' & sleep 60; kill $!; } | wc -c
, recebo 1816784896 dígitos em um minuto na minha máquina quando o programa foi compilado-O3
e 1596678144 quando foi compilado com otimizações em diamantes.Ungolfed, no UB, com explicação:
fonte
s[]
truque do mal funciona bem com o clang (apenas o instale). Estou bastante surpreso que isso realmente funcione. Para todos os efeitos, suponha que seu código nunca fique sem memória e que seus tipos de dados não sejam excedidos. Infelizmente, isso significa que simplesmente imprimir o W97 não é considerado válido. Você poderia ligarp
recursivamente? Isso eliminaria a necessidade de amain
.p
emp
si mesma sem adicionar mais código, mas se eu encontrar uma maneira, editarei novamente.Javascript (53 bytes)
A entrada deve ser string e não número (
'0'
e não apenas0
).fonte
Perl 5,
455549 bytes44 bytes, mais 1 para em
-E
vez de-e
Use como por exemplo
Isso imprime aproximações sucessivas de W ∞ e, portanto, se você esperar o suficiente, imprime, em sua última linha de saída, W ∞ no comprimento desejado, conforme necessário. Os dígitos da palavra são concatenados sem um delimitador.
Como estou no Windows, testei o requisito "pelo menos um milhão de dígitos de W ∞ ", executando-o com saída redirecionada para um arquivo e matando-o após cerca de 59 segundos, depois executando o GnuWin32
wc -L
, que imprimiu 701408733.Atualizar:
O OP esclareceu em um comentário sobre esta resposta (e provavelmente eu deveria ter percebido qualquer maneira) que a saída adicional anterior W ∞ desqualifica o acima. Então, aqui está uma solução de 55 bytes que imprime apenas W ∞ :
Usado da mesma maneira, mas com os argumentos na ordem inversa e não requer
-E
:Sem dúvida, ele pode ser jogado ainda mais, mas não vejo como fazê-lo agora.
Atualização adicional:
Dennis raspou cinco bytes usando
-a
(lendo<>
para removersub
) e reatribuindo o parâmetro passadoprint
no final doredo
bloco:Com
-ane
e lendo de<>
(ambas as entradas em uma linha, separadas por espaço, na ordem inversa); 48 + 2 bytes:E, com base nisso, raspei mais um byte (o mesmo que acima, mas agora as entradas estão na ordem correta); 47 + 2 bytes:
fonte
REXX , 48
ftw.rex
exec ftw.rex 0 1
Atualmente não posso testar o desempenho porque usei um compilador online para escrevê-lo. O "para sempre" pode ser substituído por qualquer número onde estão os números de ftw impressos (número + 2).
Também escrevi uma solução pequena (bagunçada) no Prolog. Não imaginou como testar o desempenho com este, mas provavelmente é atroz de qualquer maneira.
fonte
Python 2, 67 bytes
Aceita entrada como um par de seqüências de caracteres separadas por vírgula:
"1","0"
por exemplo, na pergunta.Não há intérprete on-line porque loops infinitos são ruins.
A saída em buffer me fez ganhar muitos bytes. :(Obrigado Dennis por apontar que 1 dígito por linha é válido.Tempo na minha máquina (significativamente mais fraca):
fonte
Dyalog APL, 9
Este usa
∇
para definir uma função recursiva. É uma tradução direta da resposta Python 3 deste xnor . Leva W 0 à direita e W -1 como argumento à esquerda, ambos devem ser vetores de caracteres.fonte
Minkolang 0.11 , 62 bytes
Experimente aqui. Espera entrada na ordem W 0 , W -1 com um espaço no meio.
Explicação
A meta-explicação para o seguinte é que, neste momento, temos dois números seguidos por uma sequência de "0" se "1" s sem separação. Se os comprimentos de W 0 e W -1 forem
a
eb
, respectivamente, os dois números na frente da pilha são<a+b>
e<a>
, nessa ordem. A palavra formada concatenando W i + 1 e W i , ou seja, W i + 1 + W i , é igual a 2 * W i + 1 - W i . Portanto, o código a seguir duplica a pilha (2 * W i + 1 ), aparece em cima<a>
elementos (- Wi) e, em seguida, substitui<a+b>
e<a>
com seus sucessores<a+2b>
e<b>
.fonte
Python 3, 32
A mesma ideia recursiva da minha resposta Haskell , exceto o prefixo, é impressa porque o Python não pode lidar com seqüências infinitas.
Utilizou um truque do Sp3000 para imprimir sem espaços, colocando a string como
end
argumento em Python 3fonte
Perl, 32 bytes
Contando o shebang como dois, a entrada é obtida de stdin, o espaço é separado como W 0 , W -1 . Saída por 1 MB de tempo a ~ 15 ms, a maioria dos quais pode ser atribuída ao lançamento do intérprete.
Uso da amostra
fonte
Prolog, 69 bytes
Exemplo de entrada: p ('1', '0')
Não foi possível remover a gravação extra.
Deveria ser capaz de melhorar isso, se eu descobrir como fazer isso.
fonte