day 19, part 2 and part 1 optimized

This commit is contained in:
Juan José Gutiérrez de Quevedo Pérez 2020-12-27 00:23:37 +01:00
parent 0eb5656a9b
commit ce00017d2d
3 changed files with 139 additions and 34 deletions

52
19/1.py
View file

@ -7,43 +7,26 @@ def parse_rule(rule):
rules = [x.split(" ") for x in rules] rules = [x.split(" ") for x in rules]
return name, rules return name, rules
def expand_rule(rules, rulename): def validate_message(rules, rule, message, pos):
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):
if rule[0][0].startswith("\""): if rule[0][0].startswith("\""):
return 1 return rule[0][0][1] == message[pos], pos + 1
elif len(rule) == 2: 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: else:
retval = 0 p = pos
for x in rule[0]: for x in rule[0]:
retval += max_length(rules, rules[x]) rv, new_p = validate_message(rules, rules[x], message, p)
return retval if not rv:
return False, pos
def validate_message(rules, rule, message): p = new_p
if max_length(rules, rule) != len(message): return True, p
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
part = 0 part = 0
rules = {} rules = {}
@ -60,7 +43,8 @@ for c in content:
retval = 0 retval = 0
for m in messages: 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 retval += 1
print(retval) print(retval)

74
19/2.py Normal file
View 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
View 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