-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
141 lines (119 loc) · 4.42 KB
/
main.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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import re
import collections
from copy import deepcopy
import math
with open('input.txt') as file:
LINES = [line.split('\n') for line in file.read().split('\n\n')]
total = 0
workflows = {}
for workflow in LINES[0]:
workflow_name, rules_string = workflow.split('{')
rules = rules_string.rstrip('}').split(',')
workflows[workflow_name.strip()] = rules
for part in LINES[1]:
x, m, a, s = map(int, re.findall(r'\d+', part))
resolve = {'x': x, 'm': m, 'a': a, 's': s}
decided = False
curr_workflow = 'in'
while not decided:
rules = workflows[curr_workflow]
last = rules[-1]
broke_out = False
for rule in rules[:-1]:
_if, _then = rule.split(':')
parameter = _if[0]
operator = _if[1]
value = int(_if[2:])
if operator == '<':
if resolve[parameter] < value:
if _then == 'A':
total += sum(resolve.values())
decided = True
broke_out = True
break
elif _then == 'R':
decided = True
broke_out = True
break
else:
curr_workflow = _then.strip()
broke_out = True
break
elif operator == '>':
if resolve[parameter] > value:
if _then == 'A':
total += sum(resolve.values())
decided = True
broke_out = True
break
elif _then == 'R':
decided = True
broke_out = True
break
else:
curr_workflow = _then.strip()
broke_out = True
break
if broke_out:
continue
if last == 'A':
total += sum(resolve.values())
decided = True
elif last == 'R':
decided = True
else:
curr_workflow = last.strip()
print(total)
total = 0
workflows = {}
for workflow in LINES[0]:
workflow_name, rules_string = workflow.split('{')
rules = rules_string.rstrip('}').split(',')
parsed_rules = []
for rule in rules[:-1]:
_if, _then = rule.split(':')
parameter = _if[0]
operator = _if[1]
value = int(_if[2:])
parsed_rules.append((parameter, operator, value, _then.strip()))
parsed_rules.append((rules[-1]))
workflows[workflow_name.strip()] = parsed_rules
res = ['x', 'm', 'a', 's']
queue = collections.deque()
queue.append(('in', (1, 4000), (1, 4000), (1, 4000), (1, 4000)))
while queue:
curr_workflow, *xmas = queue.popleft()
rules = workflows[curr_workflow]
last = rules[-1]
broke_out = False
for rule in rules[:-1]:
parameter, operator, value, _then = rule
if operator == '>':
true_xmas = deepcopy(xmas)
true_xmas[res.index(parameter)] = (
max(value + 1, xmas[res.index(parameter)][0]), xmas[res.index(parameter)][1])
xmas[res.index(parameter)] = (xmas[res.index(parameter)][0], min(value, xmas[res.index(parameter)][1]))
if _then == 'A':
total += math.prod([max(0, (b - a + 1)) for a, b in true_xmas])
elif _then == 'R':
continue
else:
queue.append((_then, *true_xmas))
elif operator == '<':
true_xmas = deepcopy(xmas)
true_xmas[res.index(parameter)] = (
xmas[res.index(parameter)][0], min(value - 1, xmas[res.index(parameter)][1]))
xmas[res.index(parameter)] = (max(value, xmas[res.index(parameter)][0]), xmas[res.index(parameter)][1])
if _then == 'A':
total += math.prod([max(0, (b - a + 1)) for a, b in true_xmas])
elif _then == 'R':
continue
else:
queue.append((_then, *true_xmas))
if last == 'A':
total += math.prod([max(0, (b - a + 1)) for a, b in xmas])
continue
elif last == 'R':
continue
queue.append((last, *xmas))
print(total)