14 for line in open(filename, "r"):
21 (rule_number,rule) = line.split(":")
22 rule_number=int(rule_number)
24 rules[rule_number] = [s.strip() for s in rule.split("|")]
28 def get_rule_regex(rulenumber):
31 for rule in rules[rulenumber]:
33 # not a character, so we're going to go down the wishing well
34 for number in rule.split(" "):
36 regex+=get_rule_regex(number)
42 if len(rules[rulenumber]) > 1 or len(rules[rulenumber][0]) > 3:
47 # because we're doing insane things, lets build the regex for rules[8] first, which is literally 42 multiple times
48 #rules[8]=["42", "42 8"]
49 #rules[11]=["42 31", "42 11 31"]
51 rules[8]=['"((' + get_rule_regex(42) + ')(?P<rule8>(' + get_rule_regex(42) + ')*))"']
52 rules[11]=['"((' + get_rule_regex(42) + '))(?P<rule11>.*)((' + get_rule_regex(31) + '))"']
54 # ok - so all the rules are in, lets build a huge regex that gets all the rules
55 pattern="^"+get_rule_regex(0)+"$"
60 matches = re.match(pattern, line)
62 if matches.group('rule11'):
63 part=matches.group('rule8') + matches.group('rule11')
67 # remove the end, and keep count, we need at least that many rule 42s to
68 # be removed from the front
69 remove_pattern=get_rule_regex(31)+"$"
70 new_part=re.sub(remove_pattern, '', part)
71 if len(new_part) == len(part):
72 # try removing a rule 42 from the start
73 remove_pattern="^" + get_rule_regex(42)
74 new_part=re.sub(remove_pattern, '', part)
75 if len(new_part) == len(part):
76 # if nothing got removed, and we're not 0 length, we're not a match
85 if rule_42_matches >= rule_31_matches:
90 print("There were {} matches in total".format(match_count))