-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathday21.py
executable file
·80 lines (58 loc) · 1.24 KB
/
day21.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
#!/usr/bin/env python3
import z3
from operator import add, sub, mul, floordiv
from utils.all import *
def calc(vals, left, right):
vals = deepcopy(vals)
var = z3.BitVec('humn', 64)
vals['humn'] = var
s = z3.Optimize()
s.add(var > 0)
for x in order:
if x in g:
a, b = g[x]
op = ops[x]
if op == '/' and (type(vals[a]) is not int or type(vals[b]) is not int):
vals[x] = vals[a] / vals[b]
else:
vals[x] = opmap[op](vals[a], vals[b])
s.add(vals[left] == vals[right])
s.minimize(var)
assert s.check() == z3.sat
m = s.model()
return m.eval(var).as_long()
advent.setup(2022, 21)
fin = advent.get_input()
ans = 0
g = defaultdict(list)
vals = {}
ops = {}
for line in fin:
a, b = line.strip().split(': ')
if b.isdigit():
vals[a] = int(b)
else:
l, op, r = b.split()
g[a].append(l)
g[a].append(r)
ops[a] = op
original_vals = deepcopy(vals)
order = toposort(g, reverse=True)
opmap = {
'*': mul,
'+': add,
'-': sub,
'/': floordiv
}
for x in order:
if x in g:
a, b = g[x]
op = ops[x]
vals[x] = opmap[op](vals[a], vals[b])
# eprint(x, a, b)
ans = vals['root']
advent.print_answer(1, ans)
left, right = g['root']
ans = calc(original_vals, left, right)
# 3408640841017497240 wrong
advent.print_answer(2, ans)