|
| 1 | +import re |
| 2 | + |
| 3 | +def build_regex(d, rulenum, is_part1): |
| 4 | + if not is_part1: |
| 5 | + if rulenum == "8": |
| 6 | + return build_regex(d, "42", is_part1) + "+" |
| 7 | + elif rulenum == "11": |
| 8 | + a = build_regex(d, "42", is_part1) |
| 9 | + b = build_regex(d, "31", is_part1) |
| 10 | + return "(?:" + "|".join(f"{a}{{{n}}}{b}{{{n}}}" for n in range(1, 100)) + ")" |
| 11 | + |
| 12 | + rule = d[rulenum] |
| 13 | + if re.fullmatch(r'"."', rule): |
| 14 | + return rule[1] |
| 15 | + else: |
| 16 | + parts = rule.split(" | ") |
| 17 | + res = [] |
| 18 | + for part in parts: |
| 19 | + nums = part.split(" ") |
| 20 | + res.append("".join(build_regex(d, n, is_part1) for n in nums)) |
| 21 | + return "(?:" + "|".join(res) + ")" |
| 22 | + |
| 23 | +with open("input.txt") as f: |
| 24 | + rules, msgs = [l.rstrip("\n") for l in f.read().split("\n\n")] |
| 25 | + |
| 26 | +d = dict([rule.split(": ") for rule in rules.split("\n")]) |
| 27 | +msgs = [x.strip() for x in msgs.split("\n")] |
| 28 | + |
| 29 | +for is_part1 in [True, False]: |
| 30 | + z = build_regex(d, "0", is_part1) |
| 31 | + print(sum([bool(re.fullmatch(z, msg)) for msg in msgs])) |
0 commit comments