This repository has been archived by the owner on Sep 6, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
challange-15.py
100 lines (77 loc) · 2.76 KB
/
challange-15.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
import operator
from json import dumps
from re import match
def parse_command(line):
(command, sign, integer) = match(r'(\w+) (\+|\-)(\d+)', line).groups()
return (command, sign, int(integer))
def command_summary(idx, line):
current = parse_command(line)
return {
'command': current,
'next': get_next_line(idx, current)
}
def load_program(read_file):
return [command_summary(idx, line) for (idx, line) in enumerate(read_file)]
def get_next_line(idx, current, goto = 'jmp'):
ops = {
'+': operator.add,
'-': operator.sub
}
(command, sign, integer) = current
return ops[sign](idx, integer) if command == goto else idx + 1
def get_possible_solutions(program):
idx = 0
last = 0
current= {}
stack = []
possible_solutions = []
while idx is not None and idx < len(program):
current = program[idx]
stack.append(idx)
possible_solutions.append({
"idx": idx,
"next": get_next_line(idx, current["command"], 'nop')
})
last = current["next"]
idx = last if last not in stack else None
return possible_solutions
def get_exit_points(program):
stack_points = [len(program)]
check_id = 0
count = 0
while count < len(stack_points):
check_id = stack_points[count]
stack_points += [
idx for idx, summary in enumerate(program)
if summary["next"] == check_id
and idx not in stack_points
]
count += 1
return stack_points
def analyze(program):
reverse_stack = get_exit_points(program)
possible_solutions = get_possible_solutions(program)
ids_to_fix = [summary['idx'] for summary in possible_solutions if summary["next"] in reverse_stack or summary["next"] > len(program)]
return ids_to_fix
# Result
with open('./inputs/input-0H.txt') as f:
program = load_program(f)
# This only outputs the line to change
# TODO: Print out the actual solution
print(analyze(program))
# Tests
with open('./inputs/test-0H.txt') as given:
assert get_next_line(0, parse_command('acc +2')) == 1
assert get_next_line(0, parse_command('nop +0')) == 1
assert get_next_line(0, parse_command('nop +2')) == 1
assert get_next_line(0, parse_command('jmp +4')) == 4
assert get_next_line(2, parse_command('jmp +4')) == 6
assert get_next_line(6, parse_command('jmp -4')) == 2
assert get_next_line(0, parse_command('jmp +0')) == 0
assert dumps(load_program(['acc +1', 'nop +0', 'jmp -2'])) == dumps([
{ 'command': ('acc', '+', 1), 'next': 1 },
{ 'command': ('nop', '+', 0), 'next': 2 },
{ 'command': ('jmp', '-', 2), 'next': 0 }
])
program = load_program(given)
print(analyze(program))