-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday19_funcs.py
105 lines (80 loc) · 2.69 KB
/
day19_funcs.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
import re
def parse_input(input_lines):
workflows = {}
parts = []
parsing_workflows = True
for line in input_lines:
if line == "":
parsing_workflows = False
continue
if parsing_workflows:
workflow = parse_workflow(line)
workflows[workflow.name] = workflow
else:
matches = re.findall(r"^{\D=(\d+),\D=(\d+),\D=(\d+),\D=(\d+)}$", line)
part = {
"x": int(matches[0][0]),
"m": int(matches[0][1]),
"a": int(matches[0][2]),
"s": int(matches[0][3])
}
parts.append(part)
return workflows, parts
def parse_workflow(line):
matches = re.findall(r"^(\w+){(.+)}$", line)
name = matches[0][0]
raw_steps = matches[0][1]
steps = []
for s in raw_steps.split(","):
matches = re.findall(r"^(\w)(<|>)(\d+):(\w+)$", s)
if matches:
var = matches[0][0]
op = matches[0][1]
num = int(matches[0][2])
next_step = matches[0][3]
steps.append(Step(next_step, var, op, num))
else:
steps.append(Step(s))
workflow = Workflow(name, steps)
return workflow
def sort_parts(workflows, parts):
accepted_parts = []
for part in parts:
next_workflow_name="in"
while next_workflow_name != "A" and next_workflow_name != "R":
next_workflow_name = workflows[next_workflow_name].execute_workflow(part)
if next_workflow_name == "A":
accepted_parts.append(part)
return accepted_parts
class Workflow:
def __init__(self, name, steps):
self.name = name
self.steps = steps
def execute_workflow(self, part):
for step in self.steps:
if step.op is None:
return step.next_workflow
if step.op == ">" and part[step.var] > step.num:
return step.next_workflow
if step.op == "<" and part[step.var] < step.num:
return step.next_workflow
def __str__(self):
workflow_str = self.name + ":\n"
for step in self.steps:
workflow_str += f" {step}\n"
return workflow_str
class Step:
def __init__(self, next_workflow, var=None, op=None, num=None):
self.next_workflow = next_workflow
self.num = num
self.var = var
self.op = op
def execute_step(self, part):
# execute and return next step
pass
def __str__(self):
if self.op is None:
return self.next_workflow
return f"{self.var}{self.op}{self.num}: {self.next_workflow}"
def __repr__(self):
return self.__str__()