2023/day19.py

97 lines
3.4 KiB
Python
Raw Normal View History

2024-01-03 20:50:55 +00:00
from pprint import pprint
import sys
def part1(workflows: dict[str, list[list[str]]], ratings: str) -> int:
result = 0
for rating in ratings.splitlines():
assert [r.split("=")[0] for r in rating[1:-1].split(",")] == list("xmas")
(x, m, a, s) = (int(r.split("=")[1]) for r in rating[1:-1].split(","))
workflow = "in"
while workflow not in "RA":
print(workflow)
for rule in workflows[workflow]:
match rule:
case [target]:
workflow = target
break
case [condition, target]:
if eval(condition):
workflow = target
break
if workflow == "A":
result += sum((x, m, a, s))
return result
def part2(workflows: dict[str, list[list[str]]]) -> int:
result = 0
stack = [("in", (1, 4001), (1, 4001), (1, 4001), (1, 4001))]
while stack:
(workflow, x, m, a, s) = stack.pop()
if workflow == "A":
print(x, m, a, s)
result += (x[1] - x[0]) * (m[1] - m[0]) * (a[1] - a[0]) * (s[1] - s[0])
continue
if workflow == "R":
continue
for rule in workflows[workflow]:
match rule:
case [target]:
stack.append((target, x, m, a, s))
case [condition, target] if ">" in condition:
(var, value_) = condition.split(">")
value = int(value_) + 1
match var:
case "x":
stack.append((target, (value, x[1]), m, a, s))
x = (x[0], value)
case "m":
stack.append((target, x, (value, m[1]), a, s))
m = (m[0], value)
case "a":
stack.append((target, x, m, (value, a[1]), s))
a = (a[0], value)
case "s":
stack.append((target, x, m, a, (value, s[1])))
s = (s[0], value)
case [condition, target] if "<" in condition:
(var, value_) = condition.split("<")
value = int(value_)
match var:
case "x":
stack.append((target, (x[0], value), m, a, s))
x = (value, x[1])
case "m":
stack.append((target, x, (m[0], value), a, s))
m = (value, m[1])
case "a":
stack.append((target, x, m, (a[0], value), s))
a = (value, a[1])
case "s":
stack.append((target, x, m, a, (s[0], value)))
s = (value, s[1])
return result
def main() -> None:
with open(sys.argv[1]) as f:
(workflows_, ratings) = f.read().split("\n\n")
workflows = {}
for workflow in workflows_.splitlines():
(name, rules_) = workflow.split("{", 1)
rules = [rule.split(":") for rule in rules_[:-1].split(",")]
workflows[name] = rules
p1 = part1(workflows, ratings)
p2 = part2(workflows)
print(p1, p2)
if __name__ == "__main__":
main()