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": 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": 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()