61 lines
1.5 KiB
Python
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()
|