-
Notifications
You must be signed in to change notification settings - Fork 0
/
part2.py
48 lines (39 loc) · 1.77 KB
/
part2.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from collections import defaultdict
from copy import deepcopy
from math import prod
def find_accepted(workflow: str, cur_condition: dict[str, list[int]]):
for i, step in enumerate(workflows[workflow]):
if isinstance(step, str):
if step == 'A':
yield cur_condition
elif step != 'R':
yield from find_accepted(step, cur_condition)
else:
key, condition, value, next_workflow = step
success_condition = deepcopy(cur_condition)
if condition == '<':
success_condition[key][1] = min(success_condition[key][1], value - 1)
cur_condition[key][0] = max(cur_condition[key][0], value)
elif condition == '>':
success_condition[key][0] = max(success_condition[key][0], value + 1)
cur_condition[key][1] = min(cur_condition[key][1], value)
if next_workflow == 'A':
yield success_condition
elif next_workflow != 'R':
yield from find_accepted(next_workflow, success_condition)
with open('input.txt') as file:
workflows = defaultdict(list)
for line in filter(None, map(str.strip, file)):
name, properties = line.removesuffix('}').split('{')
properties = properties.split(',')
if name:
for item in properties:
if ':' in item:
condition, next_workflow = item.split(':')
workflows[name].append([condition[0], condition[1], int(condition[2:]), next_workflow])
else:
workflows[name].append(item)
print(sum(
prod(right - left + 1 for left, right in condition.values())
for condition in find_accepted('in', {key: [1, 4000] for key in 'xmas'})
))