summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--21.py40
1 files changed, 40 insertions, 0 deletions
diff --git a/21.py b/21.py
new file mode 100644
index 0000000..a2c0365
--- /dev/null
+++ b/21.py
@@ -0,0 +1,40 @@
+from functools import cache
+from utils import open_day
+
+monkeys = {}
+with open_day(21) as f:
+ for line in f:
+ target, expr = line.rstrip().split(': ')
+ expr = expr.split(' ')
+ if len(expr) == 1:
+ expr = int(expr[0])
+ monkeys[target] = expr
+
+ops = {
+ '+': lambda a, b: a + b,
+ '-': lambda a, b: a - b,
+ '*': lambda a, b: a * b,
+ '/': lambda a, b: a // b,
+}
+
+@cache
+def eval_monkey(m):
+ expr = monkeys[m]
+ if isinstance(expr, int):
+ return expr
+ return ops[expr[1]](eval_monkey(expr[0]), eval_monkey(expr[2]))
+
+print(eval_monkey('root'))
+
+with open('21.z3', 'w') as f:
+ f.write(''.join(f'(declare-const {monkey} Int)\n' for monkey in monkeys.keys()))
+ for k, v in monkeys.items():
+ if k == 'humn': continue
+ if k == 'root':
+ print(f'(assert (= {v[0]} {v[2]}))', file=f)
+ continue
+ if isinstance(v, int):
+ print(f'(assert (= {k} {v}))', file=f)
+ else:
+ print(f'(assert (= {k} ({v[1]} {v[0]} {v[2]})))', file=f)
+ print('(check-sat)\n(get-model)', file=f)