-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
67 lines (46 loc) · 1.51 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import os
import re
def execute_instruction(opcode, num, acc, pos):
num = int(num)
if opcode == "nop":
pass
elif opcode == "acc":
acc += num
elif opcode == "jmp":
return acc, pos + num
else:
raise ValueError("Invalid instruction", opcode, num)
return acc, pos + 1
def execute_instructions(instructions):
acc = 0
pos = 0
executed = set()
interrupted = False
while True:
if pos >= len(instructions):
break
opcode, num = instructions[pos]
if (pos, opcode, num) in executed:
interrupted = True
break
executed.add((pos, opcode, num))
acc, pos = execute_instruction(opcode, num, acc, pos)
return acc, executed, interrupted
def main():
with open(os.path.join(os.path.dirname(__file__), "input.txt")) as f:
instructions = f.read().splitlines()
pattern = re.compile(r"(?P<opcode>[\w]+) (?P<num>[+-][0-9]+)")
instructions = [re.match(pattern, i).groups() for i in instructions]
acc, execd, _ = execute_instructions(instructions)
print("Part one:", acc)
for ins in execd:
pos, opcode, num = ins
if opcode in {"jmp", "nop"}:
instructions[pos] = ("jmp" if opcode == "nop" else "nop", num)
acc, _, interrupted = execute_instructions(instructions)
if not interrupted:
break
instructions[pos] = (opcode, num)
print("Part two:", acc)
if __name__ == "__main__":
main()