-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathday_08_2.py
More file actions
61 lines (51 loc) · 1.71 KB
/
day_08_2.py
File metadata and controls
61 lines (51 loc) · 1.71 KB
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
import re
from typing import List, Optional
with open('inputs/input_08.txt', 'r') as infile:
lines = infile.readlines()
def execute_line(line_num: int, line_list: List[str]) -> Optional[int]:
try:
line = line_list[line_num]
except IndexError:
return None # the program terminated successfully
instruction = line[:3]
number = int(re.search('[+-][0-9]+', line).group())
if instruction == 'nop':
return line_num + 1
elif instruction == 'jmp':
return line_num + number
elif instruction == 'acc':
global accumulator
accumulator += number
return line_num + 1
else:
raise ValueError(f'Line {line_num}: unknown instruction')
def swap_instruction(line_num: int) -> Optional[List[str]]:
new_line_list = lines.copy()
instruction = new_line_list[line_num][:3]
if instruction == 'acc':
return None
elif instruction == 'jmp':
new_line_list[line_num] = 'nop' + new_line_list[line_num][3:]
elif instruction == 'nop':
new_line_list[line_num] = 'jmp' + new_line_list[line_num][3:]
return new_line_list
for swap_num in range(len(lines)):
new_lines = swap_instruction(swap_num)
if new_lines is None:
continue
accumulator = 0
new_line = 0
visited_lines = {new_line}
visited = False
terminates = False
while not visited:
new_line = execute_line(new_line, new_lines)
if new_line is None:
terminates = True
break
visited = new_line in visited_lines
visited_lines.add(new_line)
if terminates:
print(f'Changing line {swap_num} breaks the loop')
print(f'Accumulator value: {accumulator}')
break