From ce00017d2d08fad09f14681e7c9b5fbade78f695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juan=20Jos=C3=A9=20Guti=C3=A9rrez=20de=20Quevedo=20P=C3=A9?= =?UTF-8?q?rez?= Date: Sun, 27 Dec 2020 00:23:37 +0100 Subject: [PATCH] day 19, part 2 and part 1 optimized --- 19/1.py | 52 +++++++++++++------------------------- 19/2.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 19/einput2 | 47 ++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+), 34 deletions(-) create mode 100644 19/2.py create mode 100644 19/einput2 diff --git a/19/1.py b/19/1.py index fc66ac6..6978479 100644 --- a/19/1.py +++ b/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) diff --git a/19/2.py b/19/2.py new file mode 100644 index 0000000..e1713d1 --- /dev/null +++ b/19/2.py @@ -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) diff --git a/19/einput2 b/19/einput2 new file mode 100644 index 0000000..f5f6d4e --- /dev/null +++ b/19/einput2 @@ -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