-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathday19.py
85 lines (68 loc) · 1.99 KB
/
day19.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
def check_sequence(grammar, seq, string):
if not seq:
yield string
else:
index, *seq = seq
for string in run(grammar, index, string):
yield from check_sequence(grammar, seq, string)
def run_expand(grammar, alt, string):
for seq in alt:
yield from check_sequence(grammar, seq, string)
def run(grammar, index, string):
if isinstance(grammar[index], list):
yield from run_expand(grammar, grammar[index], string)
else:
if string and string[0] == grammar[index]:
yield string[1:]
def match(grammar, string):
return any(m == '' for m in run(grammar, '0', string))
def part1(data):
rules, messages = data
return sum(match(rules, message) for message in messages)
def part2(data):
rules, messages = data
rules = {
**rules,
'8': [['42'], ['42', '8']],
'11': [['42', '31'], ['42', '11', '31']]
}
return sum(match(rules, message) for message in messages)
def extract_data(lines):
# e.g. rules
# {
# '0': [['4', '1', '5']],
# '1': [['2', '3'], ['3', '2']],
# '2': [['4', '4'], ['5', '5']],
# '3': [['4', '5'], ['5', '4']],
# '4': 'a',
# '5': 'b'
# }
ix = 0
rules = {}
while lines[ix] != '':
line = lines[ix]
num, rule = line.split(':')
if 'a' in rule:
rules[num] = 'a'
elif 'b' in rule:
rules[num] = 'b'
else:
rules[num] = []
for r in rule.split('|'):
rules[num].append(r.strip().split(' '))
ix += 1
# e.g. messages
# ['ababbb', 'bababa', 'abbbab', 'aaabbb', 'aaaabbb']
ix += 1
messages = []
while ix < len(lines):
messages.append(lines[ix])
ix += 1
return rules, messages
with open('day19-data.txt') as f:
inputs = [
line
for line in f.read().splitlines()
]
print(part1(extract_data(inputs)))
print(part2(extract_data(inputs)))