CJam, 25 - 25 = 0 bytes
q~1,*_@{[\{1$^}/_](;)\}/;
Esta é apenas uma porta CJam direta da resposta GolfScript abaixo, pois, depois de ler a resposta de Martin Büttner , percebi que poderia salvar um byte devido ao manuseio de tipos inteiros e de caracteres por CJam. (Basicamente, o CJam não precisa do 1&usado para forçar caracteres ASCII em bits no código GolfScript, mas requer um prefixo qpara ler a entrada.) Normalmente, consideraria essa porta trivial um truque barato, mas atingir uma pontuação zero IMO vale a pena.
De qualquer forma, este programa funciona exatamente como o programa GolfScript original abaixo; portanto, consulte as instruções de descrição e uso. Como de costume, você pode testar a versão do CJam usando esse intérprete online .
GolfScript, 26 - 25 = 1 byte
~1,*.@{[1&\{1$^}/.](;)\}/;
Essa solução repete a string de entrada apenas uma vez, então acredito que se qualifica para o bônus de -25 bytes. Ele funciona mantendo internamente uma matriz de elementos k que armazena o bit atual de cada uma das k pré-iteradas.
A entrada deve ser fornecida via stdin, no formato "1111111" 3, ou seja, como uma seqüência de caracteres 0e citada 1, seguida do número k . A saída será stdout, como uma cadeia de bits sem aspas.
Teste este código online. (Se o programa atingir o tempo limite, tente executá-lo novamente; o servidor Web GolfScript é notório por intervalos aleatórios.)
Aqui está uma versão expandida deste programa, com comentários:
~ # eval the input, leaving a string and the number k on the stack
1,* # turn the number k into an array of k zeros ("the state array")
. # make a copy of the array; it will be left on the stack, making up the
# first k bits of the output (which are always zeros)
@ # move the input string to the top of the stack, to be iterated over
{
[ # place a start-of-array marker on the stack, for later use
1& # zero out all but the lowest bit of this input byte
\ # move the state array to the top of the stack, to be iterated over
{ 1$^ } / # iterate over each element of the state array, XORing each
# element with the previous value on the stack, and leave
# the results on the stack
. # duplicate the last value on the stack (which is the output bit we want)
] # collect all values put on the stack since the last [ into an array
(; # remove the first element of the array (the input bit)
) # pop the last element (the duplicated output bit) off the array
\ # move the popped bit below the new state array on the stack
}
/ # iterate the preceding code block over the bytes in the input string
; # discard the state array, leaving just the output bits on the stack
Basicamente, como a maioria das soluções iterativas, esse código pode ser entendido como aplicando a recorrência
b i , j : = b i , ( j −1) ⊕ b ( i −1), ( j −1) ,
onde b 0, j é o j- ésimo bit de entrada (para j ≥ 1), b k , j é o j- ésimo bit de saída e b i , 0 = 0 por suposição. A diferença é que, enquanto as soluções iterativas, na verdade, calculam a recorrência "linha por linha" (ou seja, primeiro b 1, j para todos os j , depois b 2, j , etc.), essa solução a computa "coluna por coluna "(ou, mais precisamente," diagonal por diagonal "), primeiro calculando b i , i para 1 ≤ i≤ k , então b i , i +1 , então b i , i +2 , etc.
Uma vantagem (teórica) dessa abordagem é que, em princípio, esse método pode processar uma sequência de entrada arbitrariamente longa usando apenas armazenamento O ( k ). Obviamente, o intérprete GolfScript lê automaticamente toda a entrada na memória antes de executar o programa, negando essa vantagem.