12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788 |
- 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()
|