from operator import xor
from functools import reduce
class LFSR(object):
def __init__(self, taps, func, init):
self.func = func
self.state = int(init, 2)
self.width = len(init)
self.taps = [self.width - t - 1 for t in taps]
def _bit(self, b):
return (self.state & 1 << b) >> b
def step(self):
shift = reduce(self.func, (self._bit(t) for t in self.taps)) & 1
self.state >>= 1
if shift:
self.state |= 1 << (self.width - 1)
def __str__(self):
return '{:0{}b}'.format(self.state, self.width)
def xnor(a, b):
return ~xor(a, b)
def run(challenge):
taps, func, start, count = challenge.split()
taps = list(map(int, taps[1:-1].split(',')))
func = xor if func == 'XOR' else xnor
count = int(count)
reg = LFSR(taps, func, start)
print(0, reg)
for i in range(1, count + 1):
reg.step()
print(i, reg)
if __name__ == '__main__':
for challenge in ['[1,2] XOR 001 7',
'[0,2] XNOR 001 7',
'[1,2,3,7] XOR 00000001 16',
'[1,5,6,31] XOR 00000000000000000000000000000001 16']:
run(challenge)
print()
ZnJvbSBvcGVyYXRvciBpbXBvcnQgeG9yCmZyb20gZnVuY3Rvb2xzIGltcG9ydCByZWR1Y2UKCmNsYXNzIExGU1Iob2JqZWN0KToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCB0YXBzLCBmdW5jLCBpbml0KToKICAgICAgICBzZWxmLmZ1bmMgPSBmdW5jCiAgICAgICAgc2VsZi5zdGF0ZSA9IGludChpbml0LCAyKQogICAgICAgIHNlbGYud2lkdGggPSBsZW4oaW5pdCkKICAgICAgICBzZWxmLnRhcHMgPSBbc2VsZi53aWR0aCAtIHQgLSAxIGZvciB0IGluIHRhcHNdCgogICAgZGVmIF9iaXQoc2VsZiwgYik6CiAgICAgICAgcmV0dXJuIChzZWxmLnN0YXRlICYgMSA8PCBiKSA+PiBiCgogICAgZGVmIHN0ZXAoc2VsZik6CiAgICAgICAgc2hpZnQgPSByZWR1Y2Uoc2VsZi5mdW5jLCAoc2VsZi5fYml0KHQpIGZvciB0IGluIHNlbGYudGFwcykpICYgMQogICAgICAgIHNlbGYuc3RhdGUgPj49IDEKICAgICAgICBpZiBzaGlmdDoKICAgICAgICAgICAgc2VsZi5zdGF0ZSB8PSAxIDw8IChzZWxmLndpZHRoIC0gMSkKCiAgICBkZWYgX19zdHJfXyhzZWxmKToKICAgICAgICByZXR1cm4gJ3s6MHt9Yn0nLmZvcm1hdChzZWxmLnN0YXRlLCBzZWxmLndpZHRoKQoKZGVmIHhub3IoYSwgYik6CiAgICByZXR1cm4gfnhvcihhLCBiKQoKZGVmIHJ1bihjaGFsbGVuZ2UpOgogICAgdGFwcywgZnVuYywgc3RhcnQsIGNvdW50ID0gY2hhbGxlbmdlLnNwbGl0KCkKICAgIHRhcHMgPSBsaXN0KG1hcChpbnQsIHRhcHNbMTotMV0uc3BsaXQoJywnKSkpCiAgICBmdW5jID0geG9yIGlmIGZ1bmMgPT0gJ1hPUicgZWxzZSB4bm9yCiAgICBjb3VudCA9IGludChjb3VudCkKCiAgICByZWcgPSBMRlNSKHRhcHMsIGZ1bmMsIHN0YXJ0KQogICAgcHJpbnQoMCwgcmVnKQogICAgZm9yIGkgaW4gcmFuZ2UoMSwgY291bnQgKyAxKToKICAgICAgICByZWcuc3RlcCgpCiAgICAgICAgcHJpbnQoaSwgcmVnKQoKaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoKICAgIGZvciBjaGFsbGVuZ2UgaW4gWydbMSwyXSBYT1IgMDAxIDcnLAogICAgICAgICAgICAgICAgICAgICAgJ1swLDJdIFhOT1IgMDAxIDcnLAogICAgICAgICAgICAgICAgICAgICAgJ1sxLDIsMyw3XSBYT1IgMDAwMDAwMDEgMTYnLAogICAgICAgICAgICAgICAgICAgICAgJ1sxLDUsNiwzMV0gWE9SIDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxIDE2J106CiAgICAgICAgcnVuKGNoYWxsZW5nZSkKICAgICAgICBwcmludCgp