Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Instruction set
- class I:
- OutputVal = 0
- ToggleVal = 1
- MoveFward = 2
- MoveBward = 3
- JmpFIfNot = 4
- JmpBIfSet = 5
- class Tape(list):
- def expand(self, n):
- self += [0] * (n - len(self))
- def __getitem__(self, i):
- self.expand(i + 1)
- return super().__getitem__(i)
- def __setitem__(self, i, x):
- self.expand(i + 1)
- return super().__setitem__(i, x)
- def jump_table(tm):
- jumps, jump_stack = {}, []
- for ptr, instr in enumerate(tm):
- if instr == I.JmpFIfNot:
- jump_stack.append(ptr)
- elif instr == I.JmpBIfSet:
- if jump_stack:
- s = jump_stack.pop()
- jumps[s], jumps[ptr] = ptr, s
- else:
- jumps[ptr] = 0
- jumps.update({ptr: 0 for ptr in jump_stack})
- return jumps
- def print_state(tape, t):
- print(''.join(str(v) for v in tape))
- print(' ' * t + '^')
- print()
- def run(tm):
- tape, p, t = Tape(), 0, 0
- jumps = jump_table(tm)
- while p < len(tm):
- x = tm[p]
- if x == I.OutputVal: yield tape[t]
- elif x == I.ToggleVal: tape[t] = 1 - tape[t]
- elif x == I.MoveFward: t += 1
- elif x == I.MoveBward: t = t - 1 if t else 0
- elif x == I.JmpFIfNot: p = jumps[p] if tape[t] == 0 else p
- elif x == I.JmpBIfSet: p = jumps[p] if tape[t] == 1 else p
- else: raise NotImplementedError
- print_state(tape, t)
- p += 1
- # Example
- # Print the members of {0^(4-n) 1^(n + 1) | n = 0..4}
- prog = '12222213333' + 0*" Put 00001 on the tape, with 1 at the beginning" \
- + '141' + 0*" End of loop while there are still zeros" \
- + '1410215' + 0*" Output initial zeros" \
- + '14025' + 0*" Output remaining ones" \
- + '343513' + 0*" Go back, set last zero to one" \
- + '14131512' + 0*" Go back, skipping over zeros" \
- + '151' + 0*" End of loop while there are still zeros" \
- + '4025' + 0*" Output remaining ones" \
- tm = [int(x) for x in prog.strip()]
- print(''.join(map(str, run(tm))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement