CJam, 25 − 25 = 0 bytes
q~1,*_@{[\{1$^}/_](;)\}/;
This is just a straight CJam port of the GolfScript answer below, since, after reading Martin Büttner's answer, I realized that I could save one byte due to CJam's handling of integer and character types. (Basically, CJam doesn't need the 1&
used to force ASCII characters into bits in the GolfScript code, but does require a prepended q
to read the input.) I would usually consider such a trivial port a cheap trick, but achieving a zero score made it IMO worthwhile.
In any case, this program works exactly like the original GolfScript program below, so please refer to its description and usage instructions. As usual, you can test the CJam version using this online interpreter.
GolfScript, 26 − 25 = 1 byte
~1,*.@{[1&\{1$^}/.](;)\}/;
This solution iterates over the input string only once, so I believe it qualifies for the −25 byte bonus. It works by internally maintaining a k-element array that stores the current bit of each of the k pre-iterates.
Input should be given via stdin, in the format "1111111" 3
, i.e. as a quoted string of 0
and 1
characters, followed by the number k. Output will be to stdout, as a bitstring without quotes.
Test this code online. (If the program times out, try re-running it; the Web GolfScript server is notorious for random timeouts.)
Here's an expanded version of this program, with comments:
~ # 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
Basically, like most of the iterative solutions, this code can be understood as applying the recurrence
bi,j := bi,(j−1) ⊕ b(i−1),(j−1),
where b0,j is the j-th input bit (for j ≥ 1), bk,j is the j-th output bit, and bi,0 = 0 by assumption. The difference is that, whereas the iterative solutions, in effect, compute the recurrence "row by row" (i.e. first b1,j for all j, then b2,j, etc.), this solution instead computes it "column by column" (or, more accurately, "diagonal by diagonal"), first computing bi,i for 1 ≤ i ≤ k, then bi,i+1, then bi,i+2, etc.
One (theoretical) advantage of this approach is that, in principle, this method can process an arbitrarily long input string using only O(k) storage. Of course, the GolfScript interpreter automatically reads all the input into memory before running the program anyway, mostly negating this advantage.
{0-1}
-Bitfields? Also I don't understand the definition off
, where doesi
come from? What is the second argument of XOR? how do we get111
from0101
? \$\endgroup\$i
?"0 XOR 1" = 1 "1 XOR 0" = 1 "0 XOR 1" = 1
doesn't explain anything: I know how XOR works, but what exactly are we XORing and where are we storing the result? \$\endgroup\$f([a,b,c,d]) = [a^b, b^c, c^d]
. And he wants the inverse of that function, i.ef'([x,y,z]) = [a,b,c,d]
such thata^b=x
,b^c=y
,c^d=z
. \$\endgroup\$