-
Notifications
You must be signed in to change notification settings - Fork 0
/
day19.py
69 lines (52 loc) · 1.65 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
from aocd.models import Puzzle
import re
input: str = Puzzle(day=19, year=2020).input_data
rules, words = input.split("\n\n")
def map_line(line: str):
rule_number, rule_content = line.split(": ")
if "a" in rule_content:
return (rule_number, "a")
if "b" in rule_content:
return (rule_number, "b")
rule_content = rule_content.split(" | ")
rule_content = [rc.split(" ") for rc in rule_content]
return (rule_number, rule_content)
rules = [map_line(rule) for rule in rules.splitlines()]
rules = dict(rules)
words = words.splitlines()
def rule2regex(rule_number):
rule_content = rules[rule_number]
if type(rule_content) == str:
return rule_content
recursive_case = "|".join(
["".join([rule2regex(rule) for rule in option]) for option in rule_content]
)
return "(" + recursive_case + ")"
def part1():
reg = "^" + rule2regex("0") + "$"
return sum([bool(re.match(reg, word)) for word in words])
# 0 -> 42+ 42^n 31^n, with n >= 1
def testString2(s):
r42 = "^" + rule2regex("42")
r31 = "^" + rule2regex("31")
howMany42 = 0
howMany31 = 0
while True:
tryMatch = re.match(r42, s)
if tryMatch is not None:
idx = tryMatch.span()[1]
s = s[idx:]
howMany42 += 1
else:
break
while True:
tryMatch = re.match(r31, s)
if tryMatch is not None:
idx = tryMatch.span()[1]
s = s[idx:]
howMany31 += 1
else:
break
return howMany31 >= 1 and howMany42 - howMany31 >= 1 and s == ""
def part2():
return sum([testString2(word) for word in words])