-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaoc16.py
71 lines (66 loc) · 1.88 KB
/
aoc16.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
with open("input16.txt") as f:
inp = f.readline().strip()
def b2d(s):
return int('0b'+s,2)
def parse(l):
version = b2d(l[:3])
global versionsum
versionsum += version
type = b2d(l[3:6])
if type ==4: # We found a literal
i = 6
s = ''
while l[i] == '1':
s += l[i+1:i+5]
i += 5
# The last number pre-padded with 0 must be read as well
s += l[i+1:i+5]
return((i+5,b2d(s))) # We return how many bits we actually read, and the result
else: # We have an operator
# Parse the arguments
lentype = l[6]
if lentype == '0':
vs = []
lenpacks = b2d(l[7:22])
(n,v) = parse(l[22:22+lenpacks])
vs.append(v)
totlen = n
j = 22
while totlen < lenpacks:
j += n
(n,v) = parse(l[j:22+lenpacks])
totlen += n
vs.append(v)
reslen = 22+totlen
else: # lentype == '1'
vs = []
numpacks = b2d(l[7:18])
j = 18
for _ in range(numpacks):
(n,v) = parse(l[j:])
j += n
vs.append(v)
reslen = j
# Compute the result
if type == 0:
res = sum(vs)
elif type == 1:
res = 1
for v in vs:
res *= v
elif type == 2:
res = min(vs)
elif type == 3:
res = max(vs)
elif type == 5:
res = (1 if vs[0] > vs[1] else 0)
elif type == 6:
res = (1 if vs[0] < vs[1] else 0)
elif type == 7:
res = (1 if vs[0] == vs[1] else 0)
return((reslen,res))
b = bin(int('8'+inp, 16))[6:]
versionsum = 0
(n,v) = parse(b)
print(f'Sum of version numbers: {versionsum}')
print(f'Value of the expression is {v}')