#!/usr/bin/env python3 import sys import re def parse_rules(lines): rules = {} for line in lines: rule, pattern = line.split(':') alternatives = pattern.split('|') rules[int(rule)] = [a.strip(' ').split(' ') for a in alternatives] return rules def memo(f): mem = {} def helper(x): if x not in mem: mem[x] = f(x) return mem[x] return helper @memo def expr(rule): if rule == 8: return expr(42) + '+' if rule == 11: return '(?:' + expr(42) + '(?=a*(\1?+b)b*(\2?+c)))+\1' + expr(31) + ')' global rules if type(rule) is str: try: rule = int(rule) except ValueError: return rule[1] pattern = rules[rule] res = ["".join(expr(dep) for dep in alt) for alt in pattern] if len(res) == 1: return res[0] return "(" + "|".join(res) + ")" if __name__ == '__main__': rules, messages = open(sys.argv[1]).read().split('\n\n') rules = parse_rules(rules.split('\n')) count = 0 messages = messages.split("\n") for m in messages: if bool(re.match('^' + expr(0) + '$', m)): count += 1 print(count)