day 19, part 2 and part 1 optimized
This commit is contained in:
parent
0eb5656a9b
commit
ce00017d2d
52
19/1.py
52
19/1.py
|
@ -7,43 +7,26 @@ def parse_rule(rule):
|
|||
rules = [x.split(" ") for x in rules]
|
||||
return name, rules
|
||||
|
||||
def expand_rule(rules, rulename):
|
||||
rule = rules[rulename]
|
||||
for i in range(len(rule)):
|
||||
for x in range(len(rule[i])):
|
||||
if rule[i][x].startswith("\""):
|
||||
yield rule[i][x]
|
||||
else:
|
||||
yield list(expand_rule(rules, rules[rulename][i][x]))
|
||||
|
||||
def max_length(rules, rule):
|
||||
def validate_message(rules, rule, message, pos):
|
||||
if rule[0][0].startswith("\""):
|
||||
return 1
|
||||
return rule[0][0][1] == message[pos], pos + 1
|
||||
elif len(rule) == 2:
|
||||
return max_length(rules, [rule[0]])
|
||||
rv1, pos1 = validate_message(rules, [rule[0]], message, pos)
|
||||
rv2, pos2 = validate_message(rules, [rule[1]], message, pos)
|
||||
if rv1:
|
||||
return rv1, pos1
|
||||
elif rv2:
|
||||
return rv2, pos2
|
||||
else:
|
||||
return False, pos
|
||||
else:
|
||||
retval = 0
|
||||
p = pos
|
||||
for x in rule[0]:
|
||||
retval += max_length(rules, rules[x])
|
||||
return retval
|
||||
|
||||
def validate_message(rules, rule, message):
|
||||
if max_length(rules, rule) != len(message):
|
||||
return False
|
||||
if rule[0][0].startswith("\""):
|
||||
return rule[0][0][1] == message
|
||||
elif len(rule) == 2:
|
||||
l = max_length(rules, [rule[0]])
|
||||
return (validate_message(rules, [rule[0]], message[:l]) or
|
||||
validate_message(rules, [rule[1]], message[:l]))
|
||||
else:
|
||||
retval = True
|
||||
pos = 0
|
||||
for x in rule[0]:
|
||||
l = max_length(rules, rules[x])
|
||||
retval &= validate_message(rules, rules[x], message[pos:pos+l])
|
||||
pos += l
|
||||
return retval
|
||||
rv, new_p = validate_message(rules, rules[x], message, p)
|
||||
if not rv:
|
||||
return False, pos
|
||||
p = new_p
|
||||
return True, p
|
||||
|
||||
part = 0
|
||||
rules = {}
|
||||
|
@ -60,7 +43,8 @@ for c in content:
|
|||
|
||||
retval = 0
|
||||
for m in messages:
|
||||
if validate_message(rules, rules['0'], m):
|
||||
rv, pos = validate_message(rules, rules['0'], m, 0)
|
||||
if rv and pos == len(m):
|
||||
retval += 1
|
||||
|
||||
print(retval)
|
||||
|
|
74
19/2.py
Normal file
74
19/2.py
Normal file
|
@ -0,0 +1,74 @@
|
|||
with open("input") as f:
|
||||
content = [x.strip() for x in f]
|
||||
|
||||
def parse_rule(rule):
|
||||
name, rule = rule.split(": ")
|
||||
rules = rule.split(" | ")
|
||||
rules = [x.split(" ") for x in rules]
|
||||
return name, rules
|
||||
|
||||
def validate_message(rules, rule, message, pos):
|
||||
# print(f"validating rule {rule} on {message}:{pos}")
|
||||
if rules['11'] == rule:
|
||||
count = 0
|
||||
retval = True
|
||||
while retval:
|
||||
retval, new_p = validate_message(rules, rules['42'], message, pos)
|
||||
if retval:
|
||||
pos = new_p
|
||||
count += 1
|
||||
if count < 2:
|
||||
return False, pos
|
||||
count2 = 0
|
||||
retval = True
|
||||
while retval:
|
||||
retval, new_p = validate_message(rules, rules['31'], message, pos)
|
||||
if retval:
|
||||
pos = new_p
|
||||
count2 += 1
|
||||
if count2 < 1 or count2 >= count:
|
||||
return False, pos
|
||||
return True, pos
|
||||
elif rule[0][0].startswith("\""):
|
||||
if pos >= len(message):
|
||||
return False, pos
|
||||
return rule[0][0][1] == message[pos], pos + 1
|
||||
elif len(rule) == 2:
|
||||
rv1, pos1 = validate_message(rules, [rule[0]], message, pos)
|
||||
rv2, pos2 = validate_message(rules, [rule[1]], message, pos)
|
||||
if rv1:
|
||||
return rv1, pos1
|
||||
elif rv2:
|
||||
return rv2, pos2
|
||||
else:
|
||||
return False, pos
|
||||
else:
|
||||
p = pos
|
||||
for x in rule[0]:
|
||||
rv, new_p = validate_message(rules, rules[x], message, p)
|
||||
if not rv:
|
||||
return False, new_p
|
||||
p = new_p
|
||||
return True, p
|
||||
|
||||
part = 0
|
||||
rules = {}
|
||||
messages = []
|
||||
for c in content:
|
||||
if not c:
|
||||
part += 1
|
||||
continue
|
||||
if part == 0: # parsing rules
|
||||
name, rule = parse_rule(c)
|
||||
rules[name] = rule
|
||||
if part == 1: # reading messages
|
||||
messages.append(c)
|
||||
|
||||
retval = 0
|
||||
for m in messages:
|
||||
rv, pos = validate_message(rules, rules['11'], m, 0)
|
||||
if rv and pos == len(m):
|
||||
print(m)
|
||||
retval += 1
|
||||
|
||||
print(retval)
|
47
19/einput2
Normal file
47
19/einput2
Normal file
|
@ -0,0 +1,47 @@
|
|||
42: 9 14 | 10 1
|
||||
9: 14 27 | 1 26
|
||||
10: 23 14 | 28 1
|
||||
1: "a"
|
||||
11: 42 31 | 42 11 31
|
||||
5: 1 14 | 15 1
|
||||
19: 14 1 | 14 14
|
||||
12: 24 14 | 19 1
|
||||
16: 15 1 | 14 14
|
||||
31: 14 17 | 1 13
|
||||
6: 14 14 | 1 14
|
||||
2: 1 24 | 14 4
|
||||
0: 8 11
|
||||
13: 14 3 | 1 12
|
||||
15: 1 | 14
|
||||
17: 14 2 | 1 7
|
||||
23: 25 1 | 22 14
|
||||
28: 16 1
|
||||
4: 1 1
|
||||
20: 14 14 | 1 15
|
||||
3: 5 14 | 16 1
|
||||
27: 1 6 | 14 18
|
||||
14: "b"
|
||||
21: 14 1 | 1 14
|
||||
25: 1 1 | 1 14
|
||||
22: 14 14
|
||||
8: 42 | 42 8
|
||||
26: 14 22 | 1 20
|
||||
18: 15 15
|
||||
7: 14 5 | 1 21
|
||||
24: 14 1
|
||||
|
||||
abbbbbabbbaaaababbaabbbbabababbbabbbbbbabaaaa
|
||||
bbabbbbaabaabba
|
||||
babbbbaabbbbbabbbbbbaabaaabaaa
|
||||
aaabbbbbbaaaabaababaabababbabaaabbababababaaa
|
||||
bbbbbbbaaaabbbbaaabbabaaa
|
||||
bbbababbbbaaaaaaaabbababaaababaabab
|
||||
ababaaaaaabaaab
|
||||
ababaaaaabbbaba
|
||||
baabbaaaabbaaaababbaababb
|
||||
abbbbabbbbaaaababbbbbbaaaababb
|
||||
aaaaabbaabaaaaababaa
|
||||
aaaabbaaaabbaaa
|
||||
aaaabbaabbaaaaaaabbbabbbaaabbaabaaa
|
||||
babaaabbbaaabaababbaabababaaab
|
||||
aabbbbbaabbbaaaaaabbbbbababaaaaabbaaabba
|
Loading…
Reference in a new issue