-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathaoc_day16.py
130 lines (102 loc) · 2.8 KB
/
aoc_day16.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
def addr(i, r):
r[i[3]] = r[i[1]] + r[i[2]]
return r
def addi(i, r):
r[i[3]] = r[i[1]] + i[2]
return r
def mulr(i, r):
r[i[3]] = r[i[1]] * r[i[2]]
return r
def muli(i, r):
r[i[3]] = r[i[1]] * i[2]
return r
def banr(i, r):
r[i[3]] = r[i[1]] & r[i[2]]
return r
def bani(i, r):
r[i[3]] = r[i[1]] & i[2]
return r
def borr(i, r):
r[i[3]] = r[i[1]] | r[i[2]]
return r
def bori(i, r):
r[i[3]] = r[i[1]] | i[2]
return r
def setr(i, r):
r[i[3]] = r[i[1]]
return r
def seti(i, r):
r[i[3]] = i[1]
return r
def gtir(i, r):
r[i[3]] = int(i[1] > r[i[2]])
return r
def gtri(i, r):
r[i[3]] = int(r[i[1]] > i[2])
return r
def gtrr(i, r):
r[i[3]] = int(r[i[1]] > r[i[2]])
return r
def eqir(i, r):
r[i[3]] = int(i[1] == r[i[2]])
return r
def eqri(i, r):
r[i[3]] = int(r[i[1]] == i[2])
return r
def eqrr(i, r):
r[i[3]] = int(r[i[1]] == r[i[2]])
return r
opcodes = [ 'addr','addi','mulr','muli',
'banr','bani','borr','bori',
'setr','seti','gtir','gtri',
'gtrr','eqir','eqri','eqrr']
def parse(logs):
parsed = []
did_after = False
for log in logs.split('\n'):
if len(log):
if log.startswith('Before'):
before = eval(log.split(': ')[1])
elif log.startswith('After'):
after = eval(log.split(': ')[1])
did_after = True
else: inst = [int(x) for x in log.split(' ')]
if did_after:
parsed.append((before, inst, after))
did_after = False
return parsed
test = '''Before: [3, 2, 1, 1]
9 2 1 2
After: [3, 2, 2, 1]'''
samples = parse(open('input/input16_1.txt').read())
has_three = 0
for o in samples:
valid = 0
for op in opcodes:
eval_str = '%s(%s,%s)' % (op, o[1], o[0])
if eval(eval_str) == o[2]: valid += 1
if valid >= 3:
has_three += 1
print('Solution 16.1:', has_three)
codes = [None for i in range(16)]
while None in codes:
for s in samples:
valid = []
for op in opcodes:
opnum = s[1][0]
# only check the codes that haven't been validated
if op not in codes:
eval_str = '%s(%s,%s)' % (op, s[1], s[0])
if eval(eval_str) == s[2]:
valid.append((opnum,op))
# if there is only one valid solution
# assign the code to that number
if len(valid) == 1:
codes[valid[0][0]] = valid[0][1]
program = open('input/input16_2.txt').read().split('\n')
register = [0,0,0,0]
for line in program:
inst = inst = [int(x) for x in line.split(' ')]
eval_str = '%s(%s,%s)' % (codes[inst[0]], inst, register)
register = eval(eval_str)
print('Solution 16.2:', register[0])