-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathpuzzle05_refactor.py
More file actions
118 lines (112 loc) · 4.04 KB
/
puzzle05_refactor.py
File metadata and controls
118 lines (112 loc) · 4.04 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
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def load_param(program, pos, mode_param):
if mode_param == '0': # position
param = program[program[pos]]
elif mode_param == '1': # immediate
param = program[pos]
else:
raise NotImplementedError
return param
def load_addr(program, pos, mode_param):
if mode_param == '0':
addr = program[pos]
elif mode_param == '1':
addr = pos
else:
raise NotImplementedError
return addr
def run(input_program, input_values):
program = input_program[:]
index = 0
prints = []
while True:
instruction = program[index]
op_str = f"{instruction:05}" # pad with zeros if necessary
op = op_str[-2:]
mode_param3, mode_param2, mode_param1 = op_str[0], op_str[1], op_str[2]
jump = False
# add
if op == '01':
nincrement = 4
param1 = load_param(program, index + 1, mode_param1)
param2 = load_param(program, index + 2, mode_param2)
assert mode_param3 == '0'
write_addr = program[index + 3]
program[write_addr] = param1 + param2
index += nincrement
# multiply
elif op == '02':
nincrement = 4
param1 = load_param(program, index + 1, mode_param1)
param2 = load_param(program, index + 2, mode_param2)
assert mode_param3 == '0'
write_addr = program[index + 3]
program[write_addr] = param1 * param2
index += nincrement
# input_value written to address
elif op == '03':
nincrement = 2
assert mode_param1 == '0'
write_addr = program[index + 1]
input_value = input_values.pop()
program[write_addr] = input_value
index += nincrement
# output parameter
elif op == '04':
nincrement = 2
addr = load_addr(program, index + 1, mode_param1)
prints.append(program[addr])
index += nincrement
# jump if true
elif op == '05':
param1 = load_param(program, index + 1, mode_param1)
param2 = load_param(program, index + 2, mode_param2)
if param1 != 0:
index = param2
else:
nincrement = 3
index += nincrement
# jump if false
elif op == '06':
param1 = load_param(program, index + 1, mode_param1)
param2 = load_param(program, index + 2, mode_param2)
if param1 == 0:
index = param2
else:
nincrement = 3
index += nincrement
# less than
elif op == '07':
nincrement = 4
param1 = load_param(program, index + 1, mode_param1)
param2 = load_param(program, index + 2, mode_param2)
assert mode_param3 == '0'
write_addr = load_addr(program, index + 3, mode_param3)
if param1 < param2: # strict?
program[write_addr] = 1
else:
program[write_addr] = 0
index += nincrement
# equals
elif op == '08':
nincrement = 4
param1 = load_param(program, index + 1, mode_param1)
param2 = load_param(program, index + 2, mode_param2)
assert mode_param3 == '0'
write_addr = load_addr(program, index + 3, mode_param3)
if param1 == param2:
program[write_addr] = 1
else:
program[write_addr] = 0
index += nincrement
# end program
elif op == '99':
break
else:
raise NotImplementedError()
return program, prints
assert run([1002, 4, 3, 4, 33], input_values=[1])[0] == [1002, 4, 3, 4, 99]
assert run([1101, 100, -1, 4, 0], input_values=[1])[0] == [1101, 100, -1, 4, 99]
program = list(map(int, open('data/input05').read().split(',')))
assert run(program, input_values=[1])[1][-1] == 6731945
assert run(program, input_values=[5])[1][-1] == 9571668
print('all tests running')