|
@@ -0,0 +1,88 @@
|
|
|
+from queue import deque
|
|
|
+
|
|
|
+lines = [line.strip().split(": ") for line in open("21.input")]
|
|
|
+
|
|
|
+def part1():
|
|
|
+ known = {p[0]: int(p[1]) for p in lines if p[1].isdecimal()}
|
|
|
+ unknown = deque([(p[0], p[1]) for p in lines if not p[1].isdecimal()])
|
|
|
+
|
|
|
+ while "root" not in known:
|
|
|
+ name, exp = unknown.popleft()
|
|
|
+ left, op, right = exp.split(" ")
|
|
|
+ if left in known and right in known:
|
|
|
+ known[name] = eval(f"known[\"{left}\"] {op} known[\"{right}\"]")
|
|
|
+ else:
|
|
|
+ unknown.append((name, exp))
|
|
|
+
|
|
|
+ print("Part 1:", int(known["root"]))
|
|
|
+
|
|
|
+
|
|
|
+monkeys = {p[0]: p[1] for p in lines}
|
|
|
+
|
|
|
+def simplify(name):
|
|
|
+ exp = monkeys[name]
|
|
|
+
|
|
|
+ if name == "humn":
|
|
|
+ return "x"
|
|
|
+
|
|
|
+ if exp.isdecimal():
|
|
|
+ return int(exp)
|
|
|
+
|
|
|
+ left, op, right = exp.split(" ")
|
|
|
+
|
|
|
+ left, right = simplify(left), simplify(right)
|
|
|
+
|
|
|
+ if isinstance(left, int) and isinstance(right, int):
|
|
|
+ return int(eval(f"left {op} right"))
|
|
|
+ if left == "x" or right == "x":
|
|
|
+ return (left, op, right)
|
|
|
+
|
|
|
+ return (left, op, right)
|
|
|
+
|
|
|
+def solver(lhs, rhs):
|
|
|
+ while lhs != "x":
|
|
|
+ left, op, right = lhs
|
|
|
+ if op == "+":
|
|
|
+ if isinstance(left, int):
|
|
|
+ rhs -= left
|
|
|
+ lhs = right
|
|
|
+ continue
|
|
|
+ elif isinstance(right, int):
|
|
|
+ rhs -= right
|
|
|
+ lhs = left
|
|
|
+ continue
|
|
|
+ if op == "-":
|
|
|
+ if isinstance(left, int):
|
|
|
+ rhs = -rhs
|
|
|
+ rhs += left
|
|
|
+ lhs = right
|
|
|
+ continue
|
|
|
+ elif isinstance(right, int):
|
|
|
+ rhs += right
|
|
|
+ lhs = left
|
|
|
+ continue
|
|
|
+ if op == "/":
|
|
|
+ if isinstance(left, int):
|
|
|
+ raise ValueError("Cannot solve with x in denominator")
|
|
|
+ elif isinstance(right, int):
|
|
|
+ rhs *= right
|
|
|
+ lhs = left
|
|
|
+ continue
|
|
|
+ if op == "*":
|
|
|
+ if isinstance(left, int):
|
|
|
+ rhs /= left
|
|
|
+ lhs = right
|
|
|
+ continue
|
|
|
+ elif isinstance(right, int):
|
|
|
+ rhs /= right
|
|
|
+ lhs = left
|
|
|
+ continue
|
|
|
+ return rhs
|
|
|
+
|
|
|
+def part2():
|
|
|
+ left, right = monkeys["root"].split(" + ")
|
|
|
+
|
|
|
+ print("Part 2:", int(solver(simplify(left), simplify(right))))
|
|
|
+
|
|
|
+part1()
|
|
|
+part2()
|