AdventOfCode/2020/day19.py
2020-12-19 22:55:41 +01:00

61 lines
1.5 KiB
Python

import re
import sys
rules, frules, messages = {}, {}, []
srules = {}
def main():
lines = [line.rstrip() for line in sys.stdin]
step = 0
for line in lines:
if not line:
step += 1
continue
if step == 0:
rid, rcontent = line.split(": ")
if '"' in rcontent:
frules[int(rid)] = rcontent.strip('"')
else:
rules[int(rid)] = tuple(map(
lambda seq: tuple(map(int, seq.split())),
rcontent.split(" | ")
))
else:
messages.append(line)
# Part 1
rule_0 = re.compile("^" + get_regex(0) + "$")
valids = list(filter(lambda m: rule_0.match(m) is not None, messages))
print("Num valids:", len(valids))
# Part 2
del rules[8]
rule_42 = get_regex(42)
srules[8] = rule_42 + "+"
del rules[11]
rule_31 = get_regex(31)
srules[11] = "(" + "|".join(
f"{rule_42}{{{i}}}{rule_31}{{{i}}}"
for i in range(1, 10) # haha
) + ")"
rule_0 = re.compile("^" + get_regex(0) + "$")
valids = list(filter(lambda m: rule_0.match(m) is not None, messages))
print("Num valids with fake loop:", len(valids))
def get_regex(rule_id):
if (char := frules.get(rule_id)):
return char
if (regex := srules.get(rule_id)):
return regex
seq_res = []
for seq in rules[rule_id]:
seq_res.append("".join(get_regex(r) for r in seq))
return f"({'|'.join(seq_res)})"
if __name__ == "__main__":
main()