Coverage for interpreter.py: 98%
83 statements
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-24 03:21 +0000
« prev ^ index » next coverage.py v7.5.1, created at 2024-05-24 03:21 +0000
1from collections import deque
2from time import sleep
3from sys import stdin
4import argparse
7def encode(s):
8 result = []
9 for x in s:
10 result += [1, 1 if x else 0]
11 return result + [0, 0]
14def decode(s, start = 0):
15 result = []
16 i = start
17 while True:
18 pair = (1 if s[i] else 0, 1 if s[i + 1] else 0)
19 assert pair != (0, 1)
20 if pair == (0, 0):
21 return result
22 result.append(pair[1])
23 i += 2
26def move_left():
27 global current_pos
28 if current_pos == 0:
29 cells.appendleft(0)
30 else:
31 current_pos -= 1
34def move_right():
35 global current_pos
36 if current_pos == len(cells) - 1:
37 cells.append(0)
38 current_pos += 1
41def mark():
42 cells[current_pos] = 1
45def unmark():
46 cells[current_pos] = 0
49def dump():
50 print(*cells, sep='')
51 print(" " * current_pos + "^")
54if __name__ == "__main__":
55 parser = argparse.ArgumentParser(description="PTM interpreter")
56 parser.add_argument('program', type=argparse.FileType('r'), nargs='*',
57 help='file with a PTM program to interpret', default=stdin)
58 parser.add_argument('--input', type=str, help='input binary string', default='')
59 args = parser.parse_args()
61 cells = deque(encode([1 if c == "1" else 0 for c in args.input]))
62 current_pos = 0
63 cnt_ops = 0
65 for current_program in args.program:
66 with current_program as program_file:
67 original_lines = program_file.readlines()
68 lines = [line.split("#", 1)[0].split() for line in original_lines]
70 current_line = 0
71 current_cmd = 0
73 while current_line < len(lines):
74 prev_line = current_line
75 # print(original_lines[current_line], end='')
76 move_occured = False
77 while current_cmd < len(lines[current_line]):
78 cmd = lines[current_line][current_cmd]
79 cnt_ops += 1
80 if cmd == "?":
81 assert current_cmd + 2 < len(lines[current_line])
82 arg1 = lines[current_line][current_cmd + 1]
83 arg2 = lines[current_line][current_cmd + 2]
84 move_occured = True
85 current_line = (int(arg1) if cells[current_pos] else int(arg2)) - 1
86 current_cmd = 0
87 break
88 if cmd == "1":
89 mark()
90 elif cmd == "0":
91 unmark()
92 elif cmd == "<":
93 move_left()
94 elif cmd == ">":
95 move_right()
96 elif cmd == "!":
97 current_line = len(lines)
98 move_occured = True
99 break
100 current_cmd += 1
102 if lines[prev_line]:
103 # dump()
104 pass
106 if move_occured:
107 continue
109 current_line += 1
110 current_cmd = 0
111 # print(*decode(cells, current_pos), sep='')
114 print(*decode(cells, current_pos), sep='')
115 print(f"Finished in {cnt_ops} operations")