Browse Source

commit day 19, 20 and 21

19 and 20 are incomplete and nothing is optimized
Juan José Gutiérrez de Quevedo Pérez 4 months ago
parent
commit
de03aad9d6
9 changed files with 2577 additions and 0 deletions
  1. 66 0
      19/1.py
  2. 12 0
      19/einput
  3. 609 0
      19/input
  4. 37 0
      20/1.py
  5. 1728 0
      20/input
  6. 38 0
      21/1.py
  7. 50 0
      21/2.py
  8. 4 0
      21/einput
  9. 33 0
      21/input

+ 66 - 0
19/1.py

@@ -0,0 +1,66 @@
+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 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):
+    if rule[0][0].startswith("\""):
+        return 1
+    elif len(rule) == 2:
+        return max_length(rules, [rule[0]])
+    else:
+        retval = 0
+        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
+
+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:
+    if validate_message(rules, rules['0'], m):
+        retval += 1
+
+print(retval)

+ 12 - 0
19/einput

@@ -0,0 +1,12 @@
+0: 4 1 5
+1: 2 3 | 3 2
+2: 4 4 | 5 5
+3: 4 5 | 5 4
+4: "a"
+5: "b"
+
+ababbb
+bababa
+abbbab
+aaabbb
+aaaabbb

+ 609 - 0
19/input

@@ -0,0 +1,609 @@
+104: 114 114
+13: 114 77 | 29 105
+100: 20 114 | 111 29
+80: 98 29 | 102 114
+81: 29 10 | 114 89
+97: 114 51 | 29 124
+94: 114 67 | 29 64
+74: 65 114
+131: 111 114 | 65 29
+123: 118 114 | 39 29
+17: 29 70 | 114 70
+46: 89 29 | 94 114
+110: 114 50 | 29 65
+62: 29 33 | 114 72
+5: 81 29 | 2 114
+16: 29 12 | 114 103
+69: 114 3 | 29 59
+12: 121 29 | 128 114
+43: 97 114 | 25 29
+45: 64 114 | 48 29
+133: 132 29 | 70 114
+67: 114 114 | 29 29
+106: 29 64 | 114 132
+31: 29 92 | 114 38
+10: 29 67 | 114 65
+65: 29 114 | 29 29
+113: 68 114 | 68 29
+37: 64 114 | 104 29
+7: 56 114 | 129 29
+128: 115 29 | 112 114
+117: 7 114 | 49 29
+47: 29 86 | 114 60
+32: 79 114 | 64 29
+86: 111 29 | 65 114
+91: 29 5 | 114 66
+4: 79 29 | 68 114
+3: 29 68 | 114 20
+92: 29 43 | 114 62
+70: 114 29
+39: 114 127 | 29 35
+83: 29 132 | 114 111
+9: 29 125 | 114 63
+130: 29 36 | 114 108
+27: 111 114 | 132 29
+41: 67 114 | 104 29
+90: 114 50 | 29 20
+89: 14 21
+61: 114 47 | 29 126
+50: 29 29 | 114 29
+38: 114 9 | 29 57
+29: "a"
+63: 29 69 | 114 99
+105: 114 70 | 29 132
+77: 14 114 | 20 29
+51: 19 29 | 129 114
+109: 29 120 | 114 30
+54: 65 114 | 79 29
+30: 20 114 | 40 29
+72: 29 22 | 114 28
+111: 114 21 | 29 114
+84: 24 29 | 17 114
+127: 50 29 | 48 114
+125: 29 58 | 114 88
+75: 50 114 | 20 29
+118: 114 106 | 29 76
+19: 21 111
+115: 29 50
+98: 40 29 | 50 114
+126: 29 134 | 114 4
+103: 29 109 | 114 15
+26: 114 50 | 29 64
+95: 114 96 | 29 123
+101: 45 29 | 78 114
+18: 29 122 | 114 110
+58: 74 29 | 4 114
+102: 70 29 | 50 114
+0: 8 11
+28: 53 29 | 119 114
+21: 29 | 114
+11: 42 31
+122: 114 111 | 29 65
+66: 114 80 | 29 71
+24: 20 114 | 50 29
+25: 114 55 | 29 46
+87: 36 114 | 32 29
+55: 131 29 | 32 114
+76: 70 29
+44: 1 114 | 61 29
+1: 52 114 | 130 29
+96: 18 114 | 13 29
+112: 48 114 | 64 29
+71: 129 114 | 131 29
+134: 114 50 | 29 48
+22: 3 114 | 113 29
+2: 107 29 | 26 114
+99: 83 29 | 53 114
+49: 100 114 | 37 29
+35: 104 29 | 104 114
+53: 48 29 | 132 114
+48: 29 21 | 114 29
+116: 29 17 | 114 6
+121: 32 29 | 54 114
+93: 29 16 | 114 44
+119: 29 111 | 114 70
+59: 79 29 | 48 114
+34: 29 79 | 114 48
+78: 29 64 | 114 79
+107: 50 29 | 65 114
+114: "b"
+129: 14 29 | 104 114
+15: 41 114 | 90 29
+20: 21 114 | 29 29
+60: 114 104
+57: 117 114 | 82 29
+52: 75 29 | 85 114
+85: 70 29 | 40 114
+40: 114 29 | 29 114
+124: 23 114 | 34 29
+33: 116 29 | 84 114
+36: 114 68 | 29 132
+88: 133 114 | 27 29
+68: 29 114
+8: 42
+56: 29 132 | 114 40
+6: 132 114 | 79 29
+64: 114 114 | 114 29
+23: 21 40
+82: 87 114 | 101 29
+14: 21 21
+79: 29 29
+120: 114 67 | 29 132
+73: 95 29 | 91 114
+42: 73 29 | 93 114
+108: 29 48 | 114 111
+132: 114 114 | 29 114
+
+aaababbaaabababaaabaaabb
+bbabbababbbabaababbbbbbabababaaa
+baaaaaabaababbbbbaaaaaababbbbbaababbaaaaaaaaaaaa
+bababbbbaabaabbaaabababbaabbabab
+ababbaaabaabbabbbbaaabba
+aaaabaaaababbbababbaababaabbabbababaaabbaabbbbabaabbabababbbabbbaababbaaabaaabbb
+ababaababbaabbbaabbaabba
+abaabbbabbaabbaaaabababaabbbaabaabbbbbaababbaabb
+abbaaaabbbaabababbabbaabaaababaa
+aababababaabaaabaabaabba
+bbaabbbaabbabbaaaaaabbba
+bbaabbaaabbabbaaaabaaaabababbaababbabbbaabbbaabb
+abbabbbaabbbbabaabbabbbaaaabaaab
+aaaabaabaababbbaaaababbb
+baaaabaabbbbaaaabbaaabba
+aabbaaaaabbbaababaaabbaaaaababaa
+abbaababbaaabaaabbaaaaba
+bbbbbbabaaaaaababbaabababbbaaaabbaaabbba
+baaaabaaabababbbbaabbbaa
+ababbbaabaaabaaabaabbaaabaabbbbaaaababab
+babbbabaabaaaaaaaabbbaba
+ababaabaabaaaaaabbaaaaab
+aaaaabbabaaababbaaababbb
+bbaaaaaaaababbbaaaaabbabbbaaabababaabbbaaaaabbaa
+baaaabbababaabbbabaabaabaabbabbbaaabbaabbababaab
+bbaabbabababaababbbbaabbaaababab
+baaaabbbbaaababbabbbbaaa
+ababbabababababaaaabaaba
+abbabababbabaaabbbbbabab
+ababbbbbaababbbbbbaabbbabbabbaba
+abaaabbbbbabbaaabaabbbab
+abbabbaabbbbbbabaababaaa
+aaaaabaabaababbbaaaaabbaaababbaaaaabbbbbababbbbababbaababaabaaaaabbbbaabbbbbaabbbaabaaba
+baabbababaabaaabbaaababa
+bbabaabaabbaaaabbbaabbabbababbababbbbbbbaabaaabb
+baabbabbaaabbbbbbbabbbba
+bbaabbaaabaabaaabababbba
+ababbaaabaabaaabbaabbaaababbaaab
+baababbabaaaabaababbabaabbbbbbabbbbaabbbbabaaaaabbbabbbbabbaabba
+abaabbbbababaabbababababaabbabab
+bbbabbaaaabbbaabaaabaaaa
+bbabaabbbbbbbbabbabbbaaa
+abbaaaaaabaaababaabbaaba
+bbaaabaabbabbbaaaaabbaaababbaaba
+baabbaabbbaabaabaabaabba
+aaaabbabaabbbaaabaaabbba
+bbaaabaabbbaabaabbbbabab
+babbbbaabbabbaaaabababba
+bbbaabaabbbaabaabbaaababaaaabbbbaaaabaaabbbaabababbaaabb
+baaaaabababababbaaaaaababbabbbbbbabbbbbbbabbaaaababbbbabaabaaaaabbababab
+baabbaababbbbbbbbaaababbabaabbbabaaaaaaaaaaabbaabbabbbab
+baaabaabbbaaaabbbabbabab
+aaabaabbbbbabbbaaaaabbaa
+bbbbbbabbbbababbabaaabbbaaaabbbbbaabbbbb
+abababbbbaababbbbaaababbaabaabaabbbbabaabbaaaababbababbaabbabaab
+babaabbabbbababbaababbbababbbbab
+abaaaababaaababbbbabbabb
+abaaabbbaabbbbbaabbbaaabbbaaaaabaaabaaaa
+baaabaaaabbabbabbabbaaba
+abaaaaaaaabbaaaabaabaabb
+bbabaaabbaaaabbaabababba
+aababbbaabaabaaabbbbbbba
+abbabbabaabbabbabbababba
+bbbbaabbaababaabaaaabaaabbaaabaa
+baabbabbbbabaabaaabbabaa
+aaabbabaabaaabbabbbaabbbbbaababbaaababbb
+abbaababbaabbabaaabaabab
+bbbaabbbbabbbbbabaaaaaabaabbaaababbaabba
+abbabbabaababbbbababbabaabbabababbbbbaabbbbaabab
+bbabbbbbaaabbababbababab
+abbabbabaabaaabababaaaba
+aabbabbaaabaabaaaaababbb
+aaabbabaabaabaaaabbbbbaabbabaababbaabaabbbaaabbb
+bbabaabaaaabbababaaaaaabbaaababbbabaabbbbbabbbbbbbbbabbbbbbbabbbbbbabbab
+bbaaaaaababbbbaaaaaaaaab
+bbaaabaabaaaabbababbbaab
+ababbababababbaabbaaababaabbbbababbbaabb
+ababbaaaabaabaaaaaaaaaab
+baaaabbbbabbabaabaaabaaabaaaaabb
+baaaaaabaaabbabaababbbab
+abbabbaabbaaaaaabbaababbbbbaabbbaaaaaaab
+baabaabaaababbbabbaababbababbbbbaabaaaaaabaabbabbaaabaabbaaabbbbbbbaaabaabbababa
+abbbbaabbbbbbaaababbbbbaabababbbbbbbbaab
+bbbababbbaaaaabaabbabaaababaabbabbaaaaabbabbabab
+aaabbbbbaaabbbbbbabbaaba
+bbaabbaaabaaabbbababbbba
+baabbaaabbabaabbbbabbbbbbbababaaaaaaabbbabaaabaabaaabbabbbbabaaababaabaababbbbaa
+bbaababbbbaaabbbbababbaabbbaaababbaabbaa
+babbbbaabaabbaabbabbaabb
+bbbbbbabaaababbabbbabaab
+babbbbbaaaababbabbabbaba
+bbaabbabaaabaabbbabababbbbaabbaababaaaabaaaaaabaaabaaaaabbabbbbabbababaaabbbabbb
+baaaaabaabbaaaaababbbbab
+babababaabaababababaabbbabbaabbbaabbaababaababaaabaaabab
+bbbbbaaaababbbbbbabbabab
+baabaaabaaabbbabababbbab
+bbaaaabaaaaabbbababbbaabaaaaabba
+ababababbbaabbbbbabaaaba
+bbbabbbabbabaaabbbbabbaa
+bababbaaabbbbabaabbaabbbbaabbabbbbaababaabbbaaabbbabbabb
+aabababaabbabbabaababaab
+babbbababbbaaabaabbaabba
+bbabaababbaaaaaabbbbbbbb
+baababbaabaabaabbbbbabab
+baaabbaabbaabaababbaabbbbaaaabababbbbabbbbbbabba
+abbabbaaabbbbabaabbbbaabababbbbbaaabbbababbaabaabbbbbaba
+abbaaaaaababaabbaababababbbaabaabaaaabbabbbbabbababaaababbbbbabaabbaabba
+aabbabbbabababaabaaabbbb
+bbbabbbababbbbaabbbbbabb
+abababaababaabbbbaabaabb
+aaababbababbabaabbaabaaaabababbbaaababbaababaabaaaabbbbabbabaaaa
+baabbababbbabbbabbbabaab
+aaaaaabbbaabbaaaaabbbbbaaababbbabaaaaaaa
+bbaababbabaaaabbaaabbaaa
+bbaabbbbbaabaababaabaabbababbbba
+abbabbaabbaaaabbaaababbabbabaabaaabbbbbabaabaaaa
+baaaabaabaaabbaaaabaabba
+aaaabbbbaababbbabbabaaaabbbabaab
+aaabbbbbbbbbbaaaabbabbbabaaabbbb
+babbbbaabaabaaaabbabbababababbaaababbabbbbbabaaabaaaabaaaaabaaaabbabaaaa
+bbabaaaaababbaababbbbbab
+babababaaaabbbabaaaaabbb
+abbbbabbababbaabaaaabbabaabaabababbbabba
+bbabbbbbbaaabaaaababbaabbaababab
+baaaababbbaaababbaaabbbb
+bbabbaabaaabbabababbbaaa
+abbabbaaaabbabbaababbbba
+bbbabbbaabbaaaabbabbbbab
+bbaabbbabaaaabbaabbaabbbaabaaaababbaababbbbaabababbbabbabbbbbaba
+aabbabbabbabbababababbbbabbaabba
+aabbbaaabbabbaaaabbbbbab
+baaaabaaabaaaabababaaabb
+bbaabbbaabbaaabababaaaaa
+baaaabaabbabbaaababbbaaa
+bbaabbaabaabbabaaababbab
+babaabbaabbaaaaaaaaaaaaa
+bbaaabaabbabbaaaaabbaabb
+aaabaaababbbabbbaaaababababbaababaabbbba
+abbaaaabbbaabbbaaabbabaa
+ababaaabaaaababababbbaaaaaaabbaa
+babaabbaaaaaabbaaaaaaabbbbaabbaabaabbabbbbbaabab
+aababbbbaaaabbababaaabbbbaabbaaabbbbbaaaaabbbaabbabaabaa
+abaabbbbbaabbaaaaababbbaabaaaaaaababaaaa
+babbabaabbaababbabbaaaabbaaabbbb
+baaaabaaabaabbbaaaaabbabbbabbaababbbaaaa
+abbbbababaabbaababaaaaab
+babaaaaababbbabbabaabbab
+bbaaaabbaabbaaabbbaaaaba
+aabbaaaabaabbaaabaabbaabbaababab
+bbaabbaabaabbabbaaabbbabbbbbabbababaabab
+bbabaabaaaabbabaabaaaaab
+bbabababbabaabbabbbabaaaabbbaaaaabaaabaabbababba
+abbbbabaabaaabbbbabaaaba
+ababbaaaaabbabbabbbbaaab
+aaabbbabbbaabaabababaabaabbaaaaaaaaaaabbaaabbbbbbbababba
+aaabbaaaabbbaababababababababbbbbabbbbabbbaabbbbaabbaaab
+bbaabaaaababbbaabbbabbaa
+abbaabaababbbababaabababababbbaa
+babaabbbaaabbbabaaabbbbbaababbbabaabbbbaabaababb
+abbabbbaaaaaabbababbbbaabbabaaabbababbaaaaabbabbababbbba
+aaababbaababaababaaabbab
+ababaabbbbbbbabbaabbbbab
+aababbbbbbbbbaaaaaabaaba
+abaaaaaabbbbaaaababaaabb
+abbbaabaaabbaaabaaababbbbabaababbbaaaaab
+bbbbabaabaabbaababbbabbb
+bababbaaabbaababbabaaaaa
+ababbababaaabbaababbabbabbaabaabbbbbabaaabababaaaaaabababbbbaaba
+baabbabbbbabbaabbbbabbaa
+abababaabbaaababaabaabaaabaabababbabbbba
+abaaaaaaaaaabbabbababaaa
+aaabaabbaaaaaabbbbbbabba
+baaabaaabaababbbaaabbaaa
+bbbbbabbbaabbabaaabbabaa
+bbababbbbaabaaabaaabaaba
+aabbaaabaaaabbabbbabaaabbaaabbba
+babaabbaaabbaaabbabbbaba
+abbabbabbaaaabbabbbbbaba
+aaabaabaabbbababbbababab
+ababbaabababbaabbbabbabb
+aabaabaaababaababbaabaababaaabbaababbbbbbbbbbaab
+bbabaababbaaaaaaaaabbabababaaaaababbbaaa
+baabaaabaabaabaabaababbaaaaababb
+abaaaaaaaaabbbabaaaaaaab
+aaaabaabbbbbaabbabbbaababaaaaaabaababbbaaabbbaabaaaabbba
+bbabaababbaaababbababbbb
+abaaabbbbaaabaaababaaaaa
+abbbaaabbbbabaaabaaaaababaaaaaababbbabbbbabbbbab
+bbbabaaaabbbbbbbababbabababbaaba
+babbbbbababbbbbbaabbbabb
+bbaabaabbbabaababaabbbba
+bbabbaabbabaaaababbababb
+babababaabbaaababaaabbbb
+ababbbaababbaaaaababbabb
+aaaabbababbaaababaababab
+baabaababbbabaaabaabbbaaabbababbbbbbabba
+bbbaabbbbbababbbaaaaabbaaaaababa
+abbbbaabbbaaaaaababaaaaa
+bbaaababaabbbaaaaaaabaaa
+bbababbbaababbbbbabbbabb
+bbabbaaabaaaaababbaaabaaaabbaaaaaaababaa
+bbabbaaaabbabbbaabaaaabbaabbabaa
+baabbabbaababbbbbabbbaab
+ababbaabaabaaaababbababb
+babaabbbbbbaabbbbbbbaabbbbabbbaabaabbbaaabbbbbbaabbbbbab
+abbaaaabbaaaaabaaaaabbababbabbaaababaabbbbbbbbabaaabbbaa
+aabbbbbaababbababbaaaaba
+abbababaaabababaabbaaabb
+bbbaaababbaabbaabbaabbabaaababbbbaabbbbbabbbbaaaaabaaaaa
+abbabbaaaabbabbabaaabbbb
+abaabbbbbaabaaababbaaabb
+aabaabaaabababbbbaabaabb
+aaababbababaabbaabbabbaaababbbbbabbbbaaa
+babaabbbaabbbaaaabbabaab
+baaabbaabaaaabbaabbbabaa
+bbabbbbbbabaabbbbbbaabbababababbbaaabaabbababbbabaabbbbbbbababaa
+baabbaaababaaaabbbaaabba
+bbabbaaaaababbbabaababaa
+bbbbbbabababbabaaabaabbbbaaaabbaababbaaaaaaababbbaaababa
+abbbbaabaaaababbaaaabbbaabbbbbab
+abbabbabaaaaabbaababaabaaaaaaabaabaabbabbaaababa
+bbbababbabaabaaaababbbaaababbabaabbbabbaabbbaaaa
+bbbaabaaabaaaabbbabaabaa
+aaababbaabbbbabaabbaabba
+baaababbabaaabbbabbabaaabaabaaaaabbbbbba
+ababbaababbaaaaabbbbabab
+bbababbbabbbaaabaabbabbbaabaabab
+ababababbbaabbbabbaaaaba
+babbabbaaaababbaaabbaaba
+abaaaabaabbaaaaaaabbbabb
+babbaaaababbabbabababbbb
+bbabbbbbbbababbbabbbaabb
+baabbabaaabbbbabbbaaaabaabaaaaabbbabbbbbaabaaaabbaaaabbaabbaaaaabbbbbabb
+abaaabbbabaaaabbbbabbbaa
+bbbabbbabbaababaabbbabab
+abaabaabaabbbaabababbbab
+babbaaaabbbbaabbbabbbababbbabbabbaaaaabb
+baabbaaaaabbabbbbbbbabaaaaababbaaababaaa
+abbbbabbbaaaabaabbbbbbaa
+bbbbaaaaaaaaababaabaaaaa
+baaababbabbbaabaababbbba
+bbaabbbaabaabaabbbbaaaab
+abaabbbababaabbbabbbabba
+baaabbaaabbbbabbbbabbbba
+aabaaababaaabaaaaaaababb
+baaabaababaabbbbabbaabbbbababbabbbaaabaabbbbabbb
+aaaabaabbaabbaabbbaaabbb
+aaabbbababbbbabaaabbbbbb
+bababbaabbaabaabbbbbabaabbabbbbbaaabbaabbabaaaaa
+bbbabaaababaabbabbababba
+baabbaabaabbaaaabbbaaaab
+abbaaaabbbbbaabbbaaaabaabababaaa
+baaaaabababababbaabaaabb
+abbbabaabbbbabbbbabababbaabaabbabbaaabbbbaabaababaabbabb
+aabbaaabbbbababaabaaaabbabbaabbbaaaaababbaabbbba
+baabbaabaaaaaabbbabbabbababbaaaaabbbabbb
+bbbababbabaabaabaabaaaabbbbaabaababbbabaaaaabbbabbbabaabbbbaaaab
+abaabaabbaabbababbbbbaba
+aaabbbbbbbbbbabbababaabaabbbabba
+bababbaabbbbbabbbbaababbbabbbabaabaabababbabaaabbbabbaba
+abaabaaabbbbaaaababbbababbbbaaab
+bbaabbabbaabbaabbabaaabb
+abaaaababbbaabaaabaaaabbbabbbbabbbbbbaab
+aabbaaabbbaabbbbaabbabab
+baaababbbbaababbbaaaaaaa
+ababbaaabbabaaabaaaababa
+bbabaabbaaabbbbbabbbbbbbabaabaaaaabaaaaa
+baabbababaaaababaabaaabaaababbbababbbbbabbabbbab
+abaaabbaabbaaaaabbbababbaababbab
+baaaaaabbbbaaaaabbbbbbaaabbabbba
+ababbaaabbaabbabaabbabaa
+aabaaababbbaaabaabaabaaaabbaababaababbabaabbabaa
+abaaaababbabaaaaaababbbbbbababaa
+babaabbabbbbabaababbabab
+abaaaaaaabbbbbaababababbbaaabaabbbbbaaaaaaababaaabaaaaab
+aaaabbabbaabbaabaaabbbbbbabbababababbbba
+bbbbabaabbaababbbbbbbaba
+abbabaaabaaababbbbbbabab
+baabbabbabaaaabbbbbbbaab
+bbaabaaaaabbabbabababbbb
+bbabaaaaaaaabaabbbbbbbaa
+abbbbabbbbaaaaaabababbba
+bbbbbbabaaaabaabbbbbaaaaaaabbaab
+babbabbaabbbabbababaabababbbbbbaabaababaaaabbbaaabbbaaba
+abbbbbaabaaababbaaababbb
+bbbaababaabbabbababaabaaaaaabaabababbbbaabbbbbababababbbbbbaaababaabaabb
+baabaaabbababbababbbbbbabbbbaaabababbbab
+abbabababababbababababba
+abbabaaaaaabbbbbaababbbbaabaaaababaaaababbabbbba
+abaaaaaaaaababbababaabaabbbaabbbaaababbbbbbaaaaabaaabbaa
+bbbbbaaabaababbbbabbbbab
+bbaaababbabaabbbbabababbabaabaaababbbbbababbaabb
+aaaabaabbababbaabbabbbaa
+aaaabbbbabbbaaababbabaaaabbbbabaabbbbabbababbbabbabbbaabaabbababbabaabaa
+babbabbaaabaaaababbababb
+aaabaabbabbbbabbbbbaabab
+ababbbaaabbabaaabababaab
+abbbbababaaaaabaaaababbb
+ababbbbbbbabaabbaaabaaaa
+abaabbbaabbbaabaaabaaaaa
+bababbaaaaabaabbabaabbab
+bbabbaaaabaababaaaaababa
+babaabbaabababbbaabbbaab
+babbbabaaabbabbbbbaaabbb
+baaababbbaabaababbabbaaaabaaaaaabaabbbbaabbababb
+babbbbbbbbabbababbbbaaaabaabaaaaabababaabbbbbbbaaaaaaaaa
+baaabbaabaabbabababbaaab
+bbbababbabaabbbbbabbbbab
+aabbaaababbaaaabbabbaabb
+bbaaaaaabbbaabaaabbbbabbbbbababbaaabbbbbbbbabaaaabbbabab
+abbababababababaabaaaaaaaaababab
+baabbabaaaaaababbabaaaaa
+aabababaabaabaaaabbbbbba
+abaaabbaabbabababababbbb
+abbabbaaabaaaaaabbbababbaababababbbaabaabababbbabbababbaaabbbaba
+babbbbaaabaaaaaabababbabaaaabbbaabaabbbaaabaabbb
+baaaaaabbaaabbaaaaabbbbbbbbbbaab
+abaabbbaaabababaabbbbbbbabbaababbbabbaabaabbabbbbbababaabbbaabab
+bbaaaabbaaabaabbbbabaaaaabaaabbbbbabaaaaaabbbbaa
+abaabaabbababababbbbabba
+babababbbbaabbaababbbbbbbabaabbababbbbbbbaaaaababababbba
+ababbbbabbabbbaaabbaaaaaabbbabaabbbbbabb
+baabaaababaaaaaaaabababb
+aabbbaaaababbbaabbabbaaabbbaaaaaababbbab
+abbabbbabbaabaaaaaaabaaa
+aaaaaabaaaabbbabaabbbaab
+aaaaababbaaabaaabaababbabaaaabbbbaaababababaababaabbaabb
+babbbababaaaabbbababbbaaabbbaaabaabbaaaaaaaabbabaaabbaab
+bababbabaabbabbaaabaabab
+babbbababbabaabababbabab
+bbabbaabaabaabaaabbabbbb
+abbbaaabbbaabaababbabbbaabaabbaa
+aaaaaabbbbbabaabbabbbbabbbbbbbbbabbabbbbbabbabab
+aababbbaabaabaabbbbbaabbaabaabbbbbbabbbaababaaaa
+baaabaaababbbbbbaabaabbbaabbabbbabbaaaaabbaaabbaaabbaaba
+baabbababaababbbabababaabaaabbbaaabbbbaa
+bbabaabbbaaaaaabbbbabbbabbabbbbbabaaaabbbaabbbbaabbabaab
+baaaaaababaaaaaaaaaababa
+aabaaabababbbbbaaaaaaaaa
+abababaaabaaabbaaaaabaaa
+baabbaababbaaaababaaaabaabababbaabaababbaabaaabb
+babbbababbabaaabaabbbbbabbabaaaabaaabbbb
+abaabababbbabbbaaabbbbab
+ababaababbababbbabbaaaaaaababbbaaaaabbaaabaababb
+aaabbbabbbaabaabbbbaaaab
+baaabbaaabaaaabaaabbbbab
+bbbaabaabbabaaabaababbbbbabbaaaabbaaabbb
+bbabaaababaabaaaabbbaaabababaabbabbbabbbabbaabba
+ababaabbabbaaaaaabbbbbaabbabaabbbbbaabaabbbabaabaaaababb
+babbbabaabbaaababbaaabba
+baaaabbaaabbabbbbabbbbabbbabbaba
+bbbbbaaaaaaaababbaaaabbaabaaabab
+bbaabbaaabbbbabbbbbbaaab
+ababaabaabaaabbbabbbabab
+bbaabbaabaababbababbbaaa
+bababbaaaabbaaabbaaaababaaaaababbbabbabbbababbbb
+baaababbbaaaabbaaaabaaba
+bbbabbbabbaaaabbbbbaabbaabbbaaabbabbabbb
+bbaabbbbbbaaabaaaabbaaaababbabab
+abaabbbaabaaaaaaaaaabaaa
+aababbbbaababababbbabaab
+aabbaaabaaabbbababbabbabbabbaaaaaaabbbaa
+baabbabbabaaabbaabaabbaa
+bbaababaaabbbbbaabbabbababaabbbbababbabbabbbbaaa
+babababaaaaaababaabbbaba
+bbababbbbbbbbabbabaabbbbbbababbabbbabbbb
+aabababbaabaaababbaabbbbbbaaaaaaabbbbaaaababbabbaaaaaaaaabbabababbbbbbbbaaaaaaaaaaaaaaba
+abbbbbbaaaabbbbababaaaba
+baabaaabbaaaaaababbbbbba
+bbaabbaaabbbbbaababababbbaabbbba
+babbbbaababaaabbaaababaabbbabbaabaaabbabbabaaaaabbabbbba
+babaaaabbabaaaabbaaaabbaaabbbbab
+ababbababaaaabbaaabababb
+bbbbbbababababaabaabbbba
+bbaababbabbaaababababbba
+aaababbabbaaabaaaabbabbaaaaabaaabababaaa
+abaabaaaabaabababbbbaaba
+ababababaaababbababaaaaa
+bbabaaabaababaaabbabaaabbababbab
+baaabbaaaabaaabaaaabaabbbaaaaabaaaaaabaababaababbaaababaabaabbaa
+babbbbbaaabbabbbbaaaabbaaaabbbbbaaabaaba
+aababbbaaaabbbaaababbaaabbaaaababbabaabbbaaababababaaaabaabbaaaa
+bbbaabbbbbaaaabbbbaaabaaaabbabbabababaaa
+abbaababababbaaabaaaabababbbaababbbaabbbabbabaab
+aabbbaaaaabbaaabbbbbaaab
+baaaababaabbabbbaaababab
+abaabbbababbbbbbbbaaabba
+babbbbaababababbaaababbb
+baaababbaabbbababbaaabbbbbaaaaabbaaaaabbabbaaaaa
+bababbaabbaababaaabbaabbabbaaabbbabbaaabbabbbabbaaabbaaa
+bbaabbabbabbabaabbaabababaabbabbaabbaaaaaababaaabababbbb
+baabbaabbbaabbaabbbbbaab
+babaaaabbbbbabaabbaaabba
+bbbabababbbaaabaaaaaababaaabbabb
+bbababbbaabaaaababbbbaabbaaaaababbababbaaabaaabbaabbbbbb
+aaaaabbaabaaabbbbabbaabb
+abbbbaabaababbbbabaabaabbbbbbbbb
+abaaaabaaaabbbabaaabbbbbbbbbaabababbaabb
+bbbbaabbaabaaaababbabbababbabbabaababaaa
+abbbaaababbaaabaabbbabba
+bbaabbaaabababaaabbbabba
+aabababaabbbbbaaaaaaaababbbbbaabaababbab
+bbabbaababbaababaabbbbab
+bbabaaaaaaaaabbababbbbbbbbaaaabbaabaabbbbbbbbabaabbbabbbbababaab
+aaaaaabbaaababbaaaabbaab
+bbaababbabaaaababaabaaabaaaaabaa
+aaababbabbbabaaaabbbaabb
+babbbbbbbbabbbbbaaaabaabbabaaaaabbbbabbb
+baaabaabaaabbbabababbbab
+aabaaabaaabaabaaabbbaaaa
+abaabbbabbabaababbbbbaaaababbbabaabbaabbbbbabaab
+aabbabbbababbabaabbbabbb
+bbbaaabaabababbbbbbbabab
+bbbbaabbbbbbaaaaaaaabbabbbabbbbabbbaaaab
+abaabaababaaabbabbabbaba
+bbbabbbaaaaabaabaaaabbbbaababaabababaaab
+aaabaaabaabaaaabbbaaaaabbabbabaabbabababbaabbbabbaaaabbbbabbbbaaabaabbaababbbabbaaaabbbb
+bbbababaabbbbabaababaaab
+babaabbbabaabbbaabaaaabbabbbbbba
+bbaaaabbaabaaaababababba
+abbaaaaababaabaababbbaaabaabbbabaababaaa
+aabbabbbabbaaababaaaaaabaabaababaabbbabb
+bbaabbaabbabaaabababbabb
+baabbaaaaabbabbbaabbaaba
+aaaabbbabbaabbbbbaaaaabaabaaaabbaabababaabbbbaaaabbaabbababbaabaaabaaaab
+bbbabbbbaababbabbbbbbbaabbaaaabaaaabbbababbbaabbbaabaabaabaaaababbbbbabbaabbabbb
+aaabbababbaaaabbbaaaabbabbaabaabbaababab
+bbaabbbaababaabbbabbaaba
+abbbaababbabbaababbbbbaaabababbbbbbaaaaabbbbbbbbbbbbaaba
+ababababbaaaaaabbbbbaaba
+bbbbbaaabaaaaaabaaababbaaabaaaaa
+aaaabbababaababaaaabbbabababbaabbbaababbabbbbbbaaaaaaaabbbbabbbbbbbbabab
+aabaabbbbabbbabaaabaabab
+aabaabbbababaabbbbaabaabbabbabaaabbbaaaabaabaabb
+baaaabbabbbabbbabababaaa
+baabaaabbaaaaababbbabababbaaabbb
+babababababbaaaabaaabaabbbbbbbbb
+abbbbaabbaaaababbaaaabbbaababababbbbbbbabababaabaabaabba
+bbbabaaaaabbbbbaabbaabba
+abababbbbaaababbaaabbabb
+abaabaabbabaaaabababbbaaaaababaabbbaaabb
+aaaababbbaabbaabaaabbaabbbbabbbbaaabbaaabbbaaaab
+aaababbabbbabbbababababaabbaabaa
+bbaaaabbaaaaaabaaabababb
+abbbbaaabbbbbabbbaabaabbaaababaaabaabaaabbaabaaaabbbbbbbbbbbbbabababaaab
+bbbbaabbaabaabbbaabaaaababaaabaaaaabaaba
+abbabaaabaaaababbbbbbbababbbbbbbabbbaaaa
+bbaabbbbababaabbaaababab
+aabaabaaaaaabaabbbababaa
+aabaaabaabbbaaabbbbababaababbaab
+babbbbbaabababaaababaabbaabbbaab
+bbabbababbaabbbbbbaaabaaaaababbaabbbbbbbaabbbbab
+bbaababababbbbbabbabbaaababbbabb
+aabababaaababbbabaaaaabb
+babbaababaabaaabababbaababababaababbbbbb
+bbbaabbbbbbaabbaabbbaabb
+bbabbaaabbaababbaabbabbbbaabaabbaabbbaba
+abbbbbbbabababaabaaabbab
+abaaabababbbbbbaabaaabbabaaaaababbbbaaabaaaabaaabbaaabab
+abbaabbbabbbbabaaabaaabb
+bbababbbabbabbbabbbabbbbabbabbabbabaaabaaabaabbbbbbaaaaa
+baaaabaaabaaabbaabbbabbb
+aababbaaabbbabaaabaaaaabbbbbabbb
+aaabbbbbaabbabbaaabbaaaaaaabbababbaabaabbbbaababaabbbabbbbabababbabbbabb
+bbbbbababbabaababbaababaabaababaaaababbbaaabbbaabaabaababbababab
+aaababaaaabaaabbaaabaaba
+baababbbaaaabbbbbbbbabab
+abababbbbbabaaaaaabbbaaaabbabaaaababbbab
+ababababbbbbbaaabbaabbbaaabbbbbaababbbbbaaaabaaabaaabbbbbbaaaaabbabaaaaa
+aaaaaaaaabaaabaaabbabaabbaabbaaaabbbabbabbababbbbbababaabbbbabab
+baaabaaaabaaaabbbbaaaaab
+babbabbaaaabbabaabbbaaaa
+abbbaababbbababaaababbbbbabababbbbaabbabbbbbbbaabbbbbaba

+ 37 - 0
20/1.py

@@ -0,0 +1,37 @@
+with open("input") as f:
+    content = [x.strip() for x in f]
+
+def simplify_tile(tile):
+    result = []
+    result.append(tile[0])
+    result.append("".join([x[0] for x in tile]))
+    result.append("".join([x[-1] for x in tile]))
+    result.append(tile[-1])
+    return result
+
+tiles = {}
+new_tile = []
+for c in content:
+    if not c:
+        tiles[tile_id] = simplify_tile(new_tile)
+        new_tile = []
+    elif c.startswith("Tile"):
+        tile_id = int(c[5:-1])
+    else:
+        new_tile.append(c)
+
+def find_match(tiles, tile_id, border):
+    for t_id, tile in tiles.items():
+        if t_id != tile_id:
+            for b in tile:
+                if b == border or b == "".join(list(reversed(border))):
+                    return True
+
+    return False
+
+result = 1
+for tile_id, tile in tiles.items():
+    if list(map(lambda x: find_match(tiles, tile_id, x), tile)).count(True) == 2:
+        result *= tile_id
+
+print(result)

+ 1728 - 0
20/input

@@ -0,0 +1,1728 @@
+Tile 1097:
+..#...#.##
+.#..#....#
+..#....##.
+..##..#.##
+#.....#...
+#..#..##.#
+...#..##.#
+....#....#
+#.#..#.###
+...#.#.#.#
+
+Tile 1087:
+.#..######
+#........#
+.###....##
+...#.#.#.#
+....##....
+#.......##
+##..##....
+###..#...#
+##..##..#.
+.####.....
+
+Tile 3181:
+##.#..#.#.
+......###.
+.#.#..#...
+.....#..##
+..#...#...
+##.#.....#
+...####.#.
+.#........
+#.......##
+##.##.#..#
+
+Tile 3089:
+#..#..#...
+####.#..##
+.#.##.#.#.
+#..##.#..#
+........#.
+##....#...
+.....#...#
+#...#..#.#
+##.....#..
+.##.#...##
+
+Tile 1933:
+#####.##..
+..#...#...
+#.#...#..#
+.#.......#
+##.##.....
+..........
+#....#.#..
+.##....##.
+..........
+#..#..####
+
+Tile 3821:
+.#..#.###.
+#.#......#
+.....#...#
+....#....#
+##........
+......##..
+.#......##
+#...#.....
+##..#..#.#
+....###.#.
+
+Tile 3761:
+##.##.#.#.
+#.....#...
+#..#.#.#.#
+##.......#
+#..#.#...#
+..#.##....
+....#.....
+...#..#...
+#.........
+.#..##.#..
+
+Tile 1259:
+##.#.##.##
+##..#.....
+#.....#..#
+.........#
+###......#
+..##...#..
+..#....##.
+.#....##.#
+..#.##.#..
+##.#.#.##.
+
+Tile 1361:
+##.......#
+..#...#.##
+#...#..#..
+#...#.....
+#...#....#
+.......#..
+....##....
+#..##.....
+...#.#..##
+.#.##.####
+
+Tile 2917:
+#.#..##.##
+#.....##..
+##...#...#
+...#.##...
+....##..##
+....#.##.#
+##.##....#
+..#...##.#
+..##..##.#
+.##..###..
+
+Tile 2579:
+###.##....
+...##.#.#.
+...#.#.#.#
+#..#...#..
+.......##.
+.#.###.##.
+..........
+....#.....
+#.#.......
+.#.#.#####
+
+Tile 2819:
+..#..#####
+##.......#
+.....##...
+....#.....
+...#..##..
+...#.##.##
+##.#..####
+...#.#..##
+..##.#.###
+#..#....##
+
+Tile 3373:
+.###.##...
+##......#.
+..#.......
+.###...#.#
+##........
+.#..#.....
+.......#.#
+#........#
+#..##...##
+####.####.
+
+Tile 1297:
+#...#..#.#
+.........#
+#..#..#.##
+##.##.#.##
+#.#.....##
+#...#...##
+#.###.#..#
+..#...#.#.
+..##.##...
+####.#.##.
+
+Tile 2671:
+#..#....##
+#.###.#..#
+#..###..##
+##.#......
+#..##.....
+#.........
+#.#..#....
+#.#...###.
+#.##...#.#
+...#....##
+
+Tile 1367:
+#..#..#.#.
+#..#...##.
+####...#.#
+.##.#....#
+...##..#..
+.......#.#
+#.#..#...#
+...#####..
+.#.###....
+..#.#...#.
+
+Tile 3067:
+#...#.##.#
+...#.#..#.
+##...#...#
+###.#....#
+.#...##.#.
+..#.#.....
+.#...##..#
+.......#..
+.#..#..#..
+#.#####.#.
+
+Tile 2153:
+..#...###.
+..#..#..#.
+....#.#...
+....#..#.#
+........##
+#.#.#..#.#
+#...#####.
+...###..##
+......#.##
+####....#.
+
+Tile 2347:
+.##.#..#.#
+#....#..#.
+...##.....
+#.....#...
+##..#....#
+.#....##..
+...#..#..#
+##....##.#
+##....#...
+.##.#.###.
+
+Tile 3391:
+.#.####.##
+......#...
+...#.#...#
+...#...#..
+#.........
+##.##.....
+###..##...
+###...##..
+...#...#.#
+.....#.##.
+
+Tile 1409:
+....#.....
+..#..##..#
+#.#..#...#
+.#......#.
+....##....
+#.#.......
+##.#......
+###.##.#..
+##.......#
+..#..#####
+
+Tile 2879:
+#.#.#.....
+...##.####
+...#.##..#
+.....#....
+###.#.#..#
+##..#.....
+.###.....#
+###.......
+...#...#..
+..#.##.###
+
+Tile 2591:
+..###...#.
+#....#....
+#.#....#..
+#.#.#.#...
+..#...#.#.
+#.#...#...
+.#.#.....#
+.#...#....
+......##..
+..##.####.
+
+Tile 2953:
+###.#..###
+#......###
+.##...#...
+.....#....
+..#####...
+#.....#..#
+#.....#...
+#......#..
+#.....##..
+##.#..#..#
+
+Tile 2297:
+######.#..
+..#....#.#
+....#.....
+..###...##
+..#.#..###
+.#.##.#.##
+#..#......
+##...##.#.
+......#.#.
+#.#...#.#.
+
+Tile 1567:
+##.#..#.#.
+......#...
+##.....#.#
+#####....#
+##.....###
+...#...#.#
+###...#..#
+...#...#..
+##....#...
+..##....##
+
+Tile 1867:
+.##..#.#.#
+#..#...#.#
+##....#...
+....#.##..
+##..#..#.#
+#...#...##
+###.#.#..#
+.#......##
+#.##...##.
+##...##...
+
+Tile 3583:
+###...###.
+.#..#...#.
+#...##.#.#
+...#...#..
+...##.##..
+..##.#..#.
+#..#.#....
+#.#.....#.
+.###...#..
+##...####.
+
+Tile 1493:
+.#.##..#.#
+.#..##....
+..#.......
+#...#.....
+###.#.....
+....##..#.
+#.#.#.#..#
+#.#....###
+##..#....#
+.#.....##.
+
+Tile 2243:
+......#.##
+..#....#.#
+#.......#.
+..........
+#......#.#
+#..#....#.
+#.#....###
+.....#....
+.....##..#
+.###.##.##
+
+Tile 1301:
+.##...#.#.
+...#..###.
+##.....#.#
+.........#
+#...#....#
+....#....#
+...##...##
+..........
+#.##..#.##
+#.#####...
+
+Tile 2927:
+#.#..##.#.
+..###.....
+#....#....
+#..#.##.#.
+.....#....
+..#.#.#.#.
+.##.......
+#.....##.#
+..#...#..#
+#.##.#..#.
+
+Tile 1777:
+...#.#..#.
+.##....#..
+#......#..
+........#.
+.#...#...#
+#.#...#..#
+....#....#
+.....###.#
+###......#
+.#.###.##.
+
+Tile 3209:
+#.#####.#.
+#..#..#..#
+#...##...#
+#..#..#..#
+..##.....#
+.#.....#..
+#..#...##.
+....#.#...
+.#.....##.
+.......###
+
+Tile 1439:
+...#..#.#.
+#....#..#.
+##.#...###
+#....#..#.
+#.#..##..#
+.##.#...##
+.#.......#
+..........
+#.#.....##
+.##....#..
+
+Tile 2657:
+#.#.##....
+##...##...
+.#......#.
+.##.#....#
+##...##.##
+##...##...
+#####.####
+.....##.#.
+##.......#
+.##.#..#..
+
+Tile 2621:
+.#..#.####
+#...##....
+#.#...#..#
+..........
+##.......#
+..#...#.#.
+#........#
+...#.##.##
+..#.......
+####....##
+
+Tile 1511:
+#.##.#.#.#
+...#.#.#..
+##.#....##
+..##..#..#
+.#........
+......#..#
+#..#..##.#
+..#.###.##
+.##.#.#.##
+#...##.#.#
+
+Tile 2857:
+.##.####.#
+#..#..##.#
+##......#.
+#..#....#.
+..#....##.
+#...#..#..
+##...#....
+...##..#..
+#.##...###
+...#.###..
+
+Tile 3853:
+.#.#....##
+.#.#..#..#
+..........
+........#.
+.##.#.....
+#.....##.#
+#.........
+..#......#
+#.#......#
+####.##.#.
+
+Tile 3793:
+#.###.#.##
+#.#.#...#.
+#.....#.##
+....#....#
+.#.#......
+#......#..
+.#...#..#.
+##.....#.#
+.....#...#
+##.....#.#
+
+Tile 3187:
+.#..##.###
+#..#....##
+..#.#.###.
+.........#
+..##..#..#
+#.#.#.#...
+....##.#..
+...##....#
+..#.##.###
+.####..##.
+
+Tile 2087:
+#..##...#.
+.....#..#.
+...#..#.#.
+#.##....##
+##.....##.
+####...##.
+##.##....#
+#..#..#..#
+#.....#.##
+..#.######
+
+Tile 3557:
+#.#.#...##
+....#....#
+...#..#..#
+#.#......#
+#.....#...
+#...#....#
+..#.......
+##.......#
+#.....##.#
+##.##.#.#.
+
+Tile 3271:
+##.#.#..##
+#..#..#...
+#.......#.
+#.#...##..
+..........
+.##..#..##
+#.#......#
+..##.....#
+....#..###
+##.###.###
+
+Tile 2999:
+.###......
+#....##..#
+.....#....
+.##..##...
+...#.....#
+#.........
+.....#..#.
+#..#....##
+#.###..#..
+.##..#.##.
+
+Tile 2417:
+.##.##..#.
+.......#..
+.#.......#
+#.#.....#.
+..#..#...#
+#...#.#..#
+#.....#...
+......#.#.
+##.#...###
+#....##...
+
+Tile 3533:
+#.#.#####.
+#.#....##.
+#..#..####
+..#....#.#
+#..#....##
+#....#..##
+#.#.......
+#....##..#
+.##.#.....
+##..#.#...
+
+Tile 1847:
+..#..##..#
+..##..#...
+...##.#..#
+#..#......
+....#....#
+#....#....
+#.#.......
+...#.#####
+.#.#..#...
+.....#...#
+
+Tile 1553:
+#.##..#.#.
+#.##...#..
+#..#......
+..##..#.#.
+##.###....
+.#.#....#.
+#...#.#..#
+#......#..
+#.#.####.#
+##...#.###
+
+Tile 2239:
+...#.#....
+#..#......
+#.........
+#.#..#.##.
+...#......
+#...#.....
+#...#.....
+#.#.......
+.....##...
+#...###..#
+
+Tile 3001:
+...##..##.
+#........#
+##.....##.
+.....##...
+.......###
+...##....#
+#.###..##.
+#....#...#
+#..#.#...#
+#..##.##..
+
+Tile 1747:
+.#######..
+..#..#.#..
+......#...
+...#.....#
+#....#....
+#####.....
+#....##...
+.......#.#
+.........#
+....#...#.
+
+Tile 1621:
+#.#...#..#
+#...#....#
+#......#.#
+#...#.....
+..#.#...##
+#.#.......
+#.#.#...#.
+##.##.....
+.#..#.....
+#.##.#.###
+
+Tile 1399:
+...###..##
+####...#.#
+.#.#.#..#.
+###..#....
+#......#..
+.#...#.#..
+#.....#...
+....#.#...
+.##.#.#.##
+#.##..##..
+
+Tile 1373:
+#.###..###
+#..#...#..
+###.#...#.
+..##.#....
+.#.#....#.
+##.......#
+.#........
+#...#....#
+###.#...#.
+##.....##.
+
+Tile 2377:
+###.#..##.
+###.......
+#........#
+#..#.##..#
+#.........
+#..##...#.
+.#.......#
+###..#.#.#
+.#...#.#..
+#...###.##
+
+Tile 1913:
+..#.#.#...
+.....#....
+....#..#..
+.##.#..###
+#.##..#..#
+#..#....##
+.##.#.....
+#.....#...
+..#.##....
+#...#.....
+
+Tile 2089:
+.#..##....
+##........
+.#..###..#
+.....##..#
+#.......##
+.###......
+....#.....
+#....##...
+#..#.##..#
+.###.#.#..
+
+Tile 1021:
+..#.#.....
+.#.#..##.#
+#...#.#...
+#..#....##
+#..##.#..#
+...#.#....
+#..#......
+.....#.#..
+###.#..#..
+.###....#.
+
+Tile 2689:
+.####...##
+.#...#....
+...#.##.#.
+....#.#...
+.####.....
+#....#....
+.#.##.#..#
+#..#.#...#
+#.##.#...#
+####......
+
+Tile 2293:
+.#...###.#
+.##.....#.
+##..#.....
+##.......#
+#.##...###
+.##..#...#
+#.....#...
+#.##.####.
+.##.##.#..
+#...#...#.
+
+Tile 1993:
+.#..####..
+..#..##.##
+#...#.##.#
+..#...##.#
+#.#....##.
+#.#.#...#.
+........#.
+#....#...#
+..##...##.
+##.##.#..#
+
+Tile 3137:
+#...##.#..
+...#......
+..#...#..#
+..#.###..#
+..#..#.#..
+..##......
+#....##..#
+.....#....
+#.##.....#
+##.#.##...
+
+Tile 1277:
+###.###.##
+#.#.#.#...
+#.##..#..#
+#.....#..#
+..###..#.#
+..#..#...#
+.#.......#
+#........#
+##..#.#.##
+.#.##.#.##
+
+Tile 2039:
+#.#..#.#..
+#..##.##.#
+....##....
+..#.##.###
+...##....#
+.....###..
+###.......
+.##.....##
+..#......#
+....###..#
+
+Tile 3329:
+###.##.##.
+#.#.....#.
+.......###
+...#.#...#
+.#.#......
+#....#.#.#
+..#......#
+#......#..
+#..##.....
+#....#####
+
+Tile 3023:
+###...###.
+#..#..###.
+..#.....##
+...#...#.#
+...#.#.#..
+#...#..###
+##..##...#
+#.#....##.
+..#...##.#
+#..#.##..#
+
+Tile 1279:
+.#..###.#.
+..##.##...
+..#....#.#
+#.........
+#..##....#
+.....#.##.
+#........#
+.#....#.##
+##..###..#
+#..##..#.#
+
+Tile 1601:
+.##.#.###.
+......#...
+.......###
+..#.#.##.#
+#.###....#
+.....#.#.#
+##.....###
+.#.#.##..#
+#.#.#...##
+...#.##...
+
+Tile 1063:
+#..#.#...#
+#.#..#...#
+.#.#......
+#.##...###
+..#..#..##
+..#..####.
+#....#....
+#.#....#.#
+......###.
+##....#.##
+
+Tile 2659:
+..###...##
+..#......#
+#....#.###
+..#..#...#
+#....#..#.
+##........
+..#......#
+...#.....#
+#.#..#....
+####.#####
+
+Tile 2729:
+.###...#.#
+##........
+#.....#.##
+.#.......#
+..#...##.#
+..#......#
+#.##...#..
+.##.#....#
+##..###..#
+#..#.#...#
+
+Tile 1759:
+...#####.#
+..##.#.#..
+..##.#...#
+....#.#...
+#...#..#..
+..##.#...#
+##.##....#
+.......###
+##....##..
+###..###.#
+
+Tile 1181:
+.##.####.#
+###..###.#
+.#..#...##
+#....#.#..
+......####
+#.#.....#.
+#...#.##.#
+...##.#..#
+......#..#
+#.#.#..##.
+
+Tile 3389:
+######.##.
+...####.#.
+....#.....
+####....#.
+.........#
+#......#.#
+...#.#....
+....#.....
+######.###
+.#.##..###
+
+Tile 1699:
+..###.####
+..#.#..#.#
+.#.##.....
+#.#..#....
+.#..#.#.#.
+.###.#...#
+##........
+..........
+#..#......
+.#.#.##...
+
+Tile 3163:
+.#.#.#####
+##.#...#.#
+#.##.##...
+####.#.###
+#.#......#
+...#...#.#
+..#......#
+#..#......
+.#....#.##
+..#####...
+
+Tile 1193:
+##.##..##.
+..#..#....
+#........#
+#...##.##.
+#....#.##.
+#...#.#..#
+.....##..#
+#..#......
+..#...#.#.
+##.#...##.
+
+Tile 3331:
+..##....##
+#.##.##..#
+#......###
+#.....#..#
+....#..#..
+#...#.....
+######.##.
+##....##.#
+#......##.
+#.####.#..
+
+Tile 1571:
+.#...#.##.
+#...#.....
+#.#.......
+#...#.#..#
+..#....#.#
+...###....
+#.........
+#####..##.
+.##...#..#
+#.#.#.###.
+
+Tile 3307:
+.#..#..###
+#.......#.
+##.....###
+....###..#
+#.##......
+..####.#.#
+.#..#....#
+#.......##
+#.#....#..
+###.....#.
+
+Tile 2339:
+..#..#.#.#
+##..#..#.#
+##....####
+...###...#
+.##..##.##
+#..#.#..#.
+#.......##
+####.#...#
+.#...#.#..
+.#..#####.
+
+Tile 2801:
+##....####
+#.#......#
+####..#...
+#.#..#.#.#
+..#####..#
+#.....#..#
+#.......##
+#..#..##..
+..#..##.#.
+#####.###.
+
+Tile 2143:
+.##.#..#.#
+...#..#.##
+#......###
+##...#.##.
+#......###
+......##..
+#..#......
+.#.....#.#
+##..#.#.##
+...#.###..
+
+Tile 3469:
+..#...#.##
+#..##.##..
+##.......#
+#...##...#
+.#.#....#.
+##.#.....#
+...#....##
+.#.#....##
+.##.#.##.#
+.##.###.#.
+
+Tile 1559:
+#.######..
+#..#..#...
+.#..#.#...
+.#.##.....
+##....#..#
+.##.......
+...#..#..#
+##.#..#...
+..#.....##
+....##.#..
+
+Tile 3769:
+.#...##..#
+.#...#....
+#....###..
+##....#..#
+#.#......#
+##.#..#...
+....#.##.#
+...#.#....
+...##.##.#
+##.#.###.#
+
+Tile 3079:
+...#...##.
+......#...
+#.....#..#
+#.#.##.#..
+.#..#.....
+#..#.#....
+.#.#.#.#..
+..#...#..#
+....##.#.#
+######.#.#
+
+Tile 1709:
+#.......##
+#..#..#.#.
+..#.#...##
+#.#..#.##.
+##..#...##
+##.....###
+###..#....
+##...##.#.
+......#..#
+#.#######.
+
+Tile 2383:
+.###..#.#.
+#.#.#..###
+###.....##
+.#.....###
+.#.##.####
+.........#
+#.......##
+#....##...
+#.#..###..
+.#..#.#.##
+
+Tile 1549:
+.#..#.#.##
+#.#.......
+..........
+#........#
+#....#...#
+.###..#...
+####.##..#
+......#...
+.#.#.#...#
+#...#.#.##
+
+Tile 3433:
+..####...#
+..#....#.#
+.#..#..#..
+...##...#.
+....#...##
+......##..
+.##....#..
+#....#..#.
+#....#....
+##..##..#.
+
+Tile 3467:
+####.#.###
+..#...#..#
+##...##.#.
+..........
+#.#....#..
+#.......#.
+##.#.###.#
+...#....#.
+#.......##
+##...##.#.
+
+Tile 1789:
+#########.
+#.#..#...#
+#.#....#..
+.#..#..#..
+#.#.......
+#..#.....#
+...##.#...
+.#.##..#..
+..##.##.#.
+.####.####
+
+Tile 3463:
+.###.###..
+.#..##..##
+....#....#
+###....#.#
+....####..
+#.#.####.#
+#.#......#
+.......##.
+##...#..##
+.#....###.
+
+Tile 1487:
+..#.#...#.
+.....#..#.
+#.......#.
+.........#
+....##..##
+#.#..#....
+....##....
+####......
+....#.....
+##.###.#..
+
+Tile 1583:
+.....###..
+#......#..
+#.###.#.#.
+..##.....#
+.......###
+#..#....##
+#.......##
+.....#...#
+.#.......#
+.#.#.#..##
+
+Tile 3691:
+..##..###.
+#.#...##.#
+.#...#...#
+.#..##...#
+#.##.##..#
+.#...##...
+#.....##..
+..#...#.#.
+..##.##...
+#####..###
+
+Tile 2207:
+##.#.###..
+#####..#..
+.#.#......
+........#.
+#.#.......
+..#...####
+###......#
+..........
+#..##.#...
+.#.##.#.##
+
+Tile 2411:
+...#......
+.#..#.....
+#.#..#...#
+.#........
+#...###...
+.#......##
+...#.#..##
+...#.##...
+#........#
+#.#....##.
+
+Tile 3643:
+###.##.##.
+....#.#...
+##.###.#..
+.....#..##
+#......##.
+#..#...#.#
+##...#...#
+..###.#...
+#...###..#
+#...#..###
+
+Tile 3109:
+..#.###.##
+#.##....#.
+...###..##
+...##.#...
+.##......#
+.......#..
+#..##.#..#
+#.#...#...
+##.#...##.
+########.#
+
+Tile 2237:
+.#####..#.
+#..#...#..
+.........#
+........##
+#..###.#.#
+##..#.####
+#.#....##.
+.#.##.#.##
+.......#..
+#..#####..
+
+Tile 1039:
+#...#.#.#.
+..#....#.#
+#...##..#.
+...##.....
+##.......#
+##.......#
+.#####.#..
+..##.....#
+..#..#..#.
+##.#.##.##
+
+Tile 1471:
+####.###..
+.#.##....#
+.#.....#.#
+.#..#....#
+#..#.#.#.#
+#...###...
+...#.#....
+#.#.#.....
+#.........
+.#.#.#..#.
+
+Tile 3673:
+##.....###
+........##
+......###.
+##.......#
+.#..##....
+###..####.
+#.##..#..#
+###.......
+..#....##.
+#..#.#.###
+
+Tile 2903:
+#.....##..
+#.#......#
+.#....#.#.
+#......#..
+###......#
+..##....##
+#..#.....#
+#......#..
+###.#.#.#.
+..#...####
+
+Tile 3617:
+...#..##.#
+#....#....
+##....##.#
+##.#.#..##
+....#...##
+....##..#.
+###..#.###
+#......#..
+...#..#.#.
+..#.#..#.#
+
+Tile 3581:
+..#.#####.
+##..#.####
+###......#
+.##.######
+#.##.#....
+###......#
+#.........
+.....##.#.
+##....#..#
+#.#.#.#...
+
+Tile 2141:
+#..##.#...
+...#.#.###
+.#......##
+........#.
+######.##.
+.....##...
+..........
+.......###
+#.....#...
+#.###..#.#
+
+Tile 1523:
+#.....####
+...####..#
+.....#.#.#
+...#..#...
+#...#..#..
+##...####.
+..##..#.#.
+#.##.#...#
+#.#..#....
+###.##..#.
+
+Tile 3631:
+.#.....#.#
+#....##...
+###.#.##..
+.##...#...
+.#..#.#...
+.....#.#..
+..........
+.....###.#
+.#..#.....
+...#..###.
+
+Tile 2423:
+###.####..
+....#...#.
+.##.....##
+..#.....#.
+#..#.####.
+##.......#
+...#..#..#
+#..##.#...
+#.#.#.....
+.#..####..
+
+Tile 1901:
+########..
+.##...#..#
+#.....#...
+...##.#..#
+..#.#....#
+..........
+##.....#..
+.....##..#
+###....#..
+.###.#.#..
+
+Tile 1579:
+##.#..#...
+#.#...#.##
+#.#.##..##
+##.#..##.#
+..........
+#.........
+.#....#...
+.#..#.....
+...##..#..
+#.##.####.
+
+Tile 3457:
+##..##.#..
+..#....#.#
+.#.#.#.#..
+.#.......#
+#.##..#...
+.#.......#
+###.#...#.
+...#.....#
+.##.#..###
+.##..#...#
+
+Tile 2029:
+#...##.###
+###...###.
+...#..#..#
+.#....##.#
+.##.#.#..#
+..#......#
+...#.#....
+#.##.....#
+.....##.#.
+#.##..#.##
+
+Tile 3593:
+......####
+#..###..#.
+#.........
+#......###
+...#....#.
+..#.##..#.
+#.####.#..
+....#....#
+.#..#..#.#
+##...#.#.#
+
+Tile 3851:
+..###.#.##
+....#.#...
+##.#.##..#
+.....#..#.
+...#..#.#.
+..#..#.#.#
+##...##...
+....####..
+.....#.#..
+.#.....###
+
+Tile 2741:
+.#...##.##
+#.#......#
+.#.#..##.#
+##...##..#
+#.......#.
+##.......#
+.#...#...#
+..##.#.#.#
+###....#.#
+#.#..#.#.#
+
+Tile 1201:
+#.######..
+#.####.#.#
+#...#....#
+......###.
+#..#..##..
+...#.#...#
+##..#....#
+..........
+.........#
+.....#.#..
+
+Tile 2179:
+##.#..####
+.#.#......
+#...#.....
+##.#...##.
+......#..#
+.........#
+##...###.#
+#....#....
+#.........
+...#..#.##
+
+Tile 2213:
+...#.#....
+....#..#..
+.#.##....#
+.#.#....##
+###.....##
+#.....##.#
+...##.....
+##..#.....
+#...#....#
+.#.#.#.#.#
+
+Tile 2791:
+.#####....
+........##
+#..###..##
+##..#..#.#
+..#..#...#
+#..#.....#
+#.#..###.#
+#.#.......
+#........#
+.##...#.#.
+
+Tile 1447:
+..#.###...
+......#...
+....#..###
+#..##..##.
+....#..#.#
+.#..#..###
+##.##.##.#
+.#....#.##
+...#..#...
+###.#.##.#
+
+Tile 1637:
+.######.##
+#.##...#.#
+.#....#...
+##.#......
+..#...####
+.#........
+##..#..#..
+#.........
+.....##...
+.#.##.##.#
+
+Tile 3943:
+##...#....
+#.#...#...
+##....#.##
+..#..#..#.
+#.......##
+#....##...
+#...######
+#...#.....
+..##.#....
+.##..####.
+
+Tile 1811:
+.#####.#..
+#....#..##
+#.#..#.#.#
+.....#..##
+..#..#.#..
+.#.##....#
+#.#....#..
+#..##....#
+#......#.#
+...###..##
+
+Tile 2281:
+..#...#...
+.##.....##
+#....##...
+.......##.
+.#..##.#..
+..##...#.#
+#.......##
+#####..#.#
+#..##.#...
+....##..##
+
+Tile 1877:
+#.#.#.#.#.
+......#...
+.#.....#.#
+##.###...#
+###..##.#.
+....##...#
+##..######
+.#..##....
+#.#.....##
+..###.###.
+
+Tile 1163:
+.##.###...
+...#..##.#
+....##..##
+.....#....
+.####....#
+#.......##
+#..#.....#
+......#..#
+......#..#
+..###..###
+
+Tile 1873:
+####.....#
+...#.##...
+......#..#
+.#.##.....
+#..#.#...#
+#..###....
+##....#...
+...##..#.#
+#..#.....#
+#...#.#.##
+
+Tile 2521:
+#..##..#..
+..##..#...
+#.##.....#
+#...#.##..
+...#.....#
+.##..#.#.#
+###..##...
+#..##.....
+##.....##.
+###....##.
+
+Tile 2711:
+.#.#.###.#
+....#.##..
+....#....#
+#...#.##.#
+#...##.#..
+#...#.####
+#.##.....#
+..#..#....
+#.......##
+###.##.#..
+
+Tile 2477:
+.....#.##.
+....#..###
+....##.#..
+#..#......
+....#.#..#
+.#....#...
+.#..#....#
+#..#..#..#
+...#.#....
+#.###...##
+
+Tile 3571:
+###..#####
+#.#.#...##
+...#.....#
+.#.....#..
+#.#.....#.
+#..###...#
+....##...#
+....####.#
+#..##.#...
+..##.##...
+
+Tile 1831:
+##..#.....
+......#..#
+#......##.
+##.......#
+...##...#.
+..#.##.#..
+...#.##..#
+##.....#..
+#...#.##..
+##....#.##
+
+Tile 2287:
+##.##...#.
+...#......
+...#.#....
+...#....##
+#........#
+..#...##.#
+#..#......
+..#.......
+.........#
+.#....#.#.
+
+Tile 2939:
+..#.##.#.#
+##.##....#
+.#......#.
+#..#..#..#
+.##.#...##
+#..###...#
+..#......#
+...#.....#
+#........#
+.#.###..#.
+
+Tile 3671:
+.##.#..###
+#.........
+.##.#.#..#
+...#.....#
+.####....#
+.......###
+.......#.#
+#.#....##.
+##.#......
+.###..#..#
+
+Tile 3217:
+#...#.##.#
+#.........
+######....
+#...#....#
+#.....#.#.
+#.#..##..#
+#.#.##....
+#...#...##
+.###.#..##
+...#.##..#
+
+Tile 3313:
+####.#...#
+...####.##
+..#...##..
+...#.....#
+..##.#..#.
+.###.#####
+...##.#.##
+...##..###
+...#.#.###
+...##...##
+
+Tile 1879:
+.#.###.#..
+...#..#.#.
+.#......##
+.#.#...#..
+.#....#...
+##.#...#.#
+.....#....
+....#.#.##
+#.#....###
+.#..###...
+

+ 38 - 0
21/1.py

@@ -0,0 +1,38 @@
+with open("input") as f:
+    content = [x.strip().strip(")") for x in f]
+
+data = []
+for c in content:
+    ingredients, alergens = c.split(" (contains ")
+    ingredients = ingredients.split(" ")
+    alergens = alergens.split(", ")
+    data.append((ingredients, alergens))
+
+alergens = []
+ingredients = []
+for ing, al in data:
+    alergens.extend(al)
+    ingredients.extend(ing)
+
+alergens = list(set(alergens))
+ingredients = list(set(ingredients))
+found_ingredients = []
+ing_ale = {}
+for al in alergens:
+    poss = None
+    for d in data:
+        if al in d[1]:
+            if poss is None:
+                poss = set(d[0])
+            else:
+                poss &= set(d[0])
+    ing_ale[al] = poss
+    found_ingredients.extend(list(poss))
+
+no_alergens_ing = set(ingredients) - set(found_ingredients)
+count = 0
+for a in no_alergens_ing:
+    for i, al in data:
+        count += i.count(a)
+
+print(count)

+ 50 - 0
21/2.py

@@ -0,0 +1,50 @@
+with open("input") as f:
+    content = [x.strip().strip(")") for x in f]
+
+data = []
+for c in content:
+    ingredients, alergens = c.split(" (contains ")
+    ingredients = ingredients.split(" ")
+    alergens = alergens.split(", ")
+    data.append((ingredients, alergens))
+
+alergens = []
+ingredients = []
+for ing, al in data:
+    alergens.extend(al)
+    ingredients.extend(ing)
+
+alergens = list(set(alergens))
+ingredients = list(set(ingredients))
+found_ingredients = []
+ing_ale = {}
+for al in alergens:
+    poss = None
+    for d in data:
+        if al in d[1]:
+            if poss is None:
+                poss = set(d[0])
+            else:
+                poss &= set(d[0])
+    ing_ale[al] = list(poss)
+    found_ingredients.extend(list(poss))
+
+definitives = set()
+changes_made = True
+while changes_made:
+    changes_made = False
+    for ale, ing in ing_ale.items():
+        if len(ing) == 1 and ing[0] not in definitives:
+            definitives.add(ing[0])
+            changes_made = True
+    for ale, ing in ing_ale.items():
+        if len(ing) > 1:
+            ingredients = set(ing_ale[ale])
+            ing_ale[ale] = list(ingredients - definitives)
+            changes_made = True
+
+result = []
+for al in sorted(ing_ale.keys()):
+    result.append(ing_ale[al][0])
+
+print(",".join(result))

+ 4 - 0
21/einput

@@ -0,0 +1,4 @@
+mxmxvkd kfcds sqjhc nhms (contains dairy, fish)
+trh fvjkl sbzzf mxmxvkd (contains dairy)
+sqjhc fvjkl (contains soy)
+sqjhc mxmxvkd sbzzf (contains fish)

+ 33 - 0
21/input

@@ -0,0 +1,33 @@
+kxddqq qjnqkj slhjm kmvqht stf kdggj szjdxh tddgr zbnv xfrhjm cdqqt nzp zcdcdf kxzkbk brfpvc rgxnd jmpj xxrck nfjl fdm nddjz nvhhp kkxjgg kpsdtv rvfhqbz zggxkc zkmbc pmjzb dqbjj bmvpz kdxmz prs krjt smrks cxbqtf ccsxr brfpl rdn qndk bvlksl nnlg pcjsl kgbzf jkbrhq fllssz vfs jzlflq jpcsh cmmpcm sxvr zmsh tcl nnrn ljzcbx tmcql dxftvrth fvvrc fnpdz pbbhtd qjxbtlc sltqs hpnnf dhqfbv xpjdsc btfh fxsxh qpxhfp fhbldf mzjhbl ckrj xzrn czvgtl dqnd hlvl jcfsd xgf pngbxj svhqc mpzz lhnd nsmss mctnbp nnffp nhvx jxmg hmm (contains wheat, shellfish)
+zcdcdf fxsxh mqls kpsdtv fllssz llhzxnrz sxbjr svsq xfrhjm tvxxn zggxkc znnf czplkc rblrbnhp pzmg kdggj nzlpn mzjhbl fgvhf dnjjt vlfgsn nhvx kgbzf fvvrc dbjtns jmpj fnzgd rgxnd lnljt hrrbkv jrrqzc ckrj lmxrnmg rmpf jcfsd xgf bvlksl jvgxg tddgr tcl cxbqtf kcj rrnhxk kksxbr xbtfvdn hpnnf hdm sfxmr qlhm xjkk dxjdbh kfjf dqbjj czvgtl szjdxh slhjm rtct nvhhp svhqc pzk (contains soy, dairy, shellfish)
+kfjf tmcql fvvrc zmsh jrdpn nddjz zcdcdf sltqs dhqfbv tpmkh mfmcgt kgbzf xbtfvdn jxdn czplkc ztx rmpf ljzcbx kcj nzp fnzgd jcfsd xzrn qjnqkj nlcqt lzmfqvz hxltpq trfmsz dxftvrth hchsm kpsdtv dqbjj kmvqht fllssz pzmg kxzkbk jkbrhq vfs snkk pzk (contains peanuts)
+tpmkh hxltpq kksxbr nkfjx zkmbc ccsxr kqdk dhqfbv zggxkc tvxxn fvvrc lmxrnmg zbnv vxd jpcsh jzlflq kgvmlg jqvppk rmpf mpzz fcnbzf qpxhfp stf ndvvpgr bmvpz nhvx vmnfl zcdcdf dqbjj mctnbp qkkkvb skr jccbbc dvkcq pcjsl jhc tdkfbq kkxjgg znnf tmcql rrnhxk rrbklsh nlcqt fdm cdqqt kzmfh zrxk dxftvrth czvgtl sfxmr xdzlvg kbrdv msczg jmpj fzmcnxjx ppv kdxmz krjt hpnnf qlhm nfjl tddgr jrdpn dqnd prs dxjdbh fllssz hlvl kpsdtv nnlg jfbvzd nzlpn pzk bvlksl qjnqkj brfpvc hdm sltqs trfmsz cmmpcm fxsxh brfpl xjkk zpmqcv qxctmd xfrhjm xhlfkd pzmg mvzs bnjmx (contains peanuts)
+rhkxdmvz nnffp pcxfhk tvxxn ccsxr ddnql fvvrc mpzz jcfsd hlfnt gfth kkxjgg lzmfqvz llhzxnrz dxftvrth rrbklsh jmpj kpsdtv sfxmr bzbm tksln tcl szjdxh rkgqk zcdcdf kksxbr fllssz mvzs sxvr hblgrjgp xjkk rgxnd nkfjx vfs brfpl qndk mctnbp prmglh nhvx rjqrpb lnljt lgzmz nlcqt msczg qpxhfp xxrck nsmss pzmg smrks kgbzf znkx dsghqp fcnbzf lbxd pmjzb nvhhp bnjmx qgqqm jrdpn (contains dairy, nuts, wheat)
+nzp rkgqk ppv xgf cxbqtf zph jrrqzc btfh dxjdbh kpsdtv mzjhbl ktqn jcfsd fvvrc sxvr mfmcgt hmm djffq gmdxrp slhjm kqdk ccsxr rvfhqbz trfmsz jrdpn rgxnd kxzkbk dbjtns qkkkvb dqnd hxltpq jpcsh dgc qpstz krjt tdkfbq skr kcj ddnql nnffp qxctmd qpxhfp bbljn pzmg hvgxt ztx nlcqt kgbzf dqbjj tksln fllssz rblrbnhp pmjzb (contains peanuts)
+hvgxt jvgxg fxsxh ddnql cdqqt krjt ppv vlfgsn brfpvc llhzxnrz jrdpn qndk fllssz nhvx mctnbp sxbjr svhqc snkk kgbzf fvvrc zbnv rtct lnljt nnffp nddjz xxrck dsghqp kdggj hchsm qjxbtlc dnjjt bzbm brfpl dqnd hxbbn prs jmpj slhjm pngbxj dxjdbh kcj rbhjgg qlhm qpxhfp tfbcbzz xhlfkd gfth trfmsz tpmkh fgvhf mvzs nkfjx dcj ndvvpgr pmjzb dqbjj zpmqcv ccsxr bbljn jnpbc rmpf ckrj hxltpq kpsdtv zcdcdf qgqqm jfbvzd lbxd nzlpn hpnnf zzzgx zmsh hdm zvvffr vxd xgf (contains nuts, eggs)
+ztx jkbrhq jzlflq xzrn cmmpcm znkx sxbjr qpxhfp rjqrpb vmnfl rtct rbhjgg zrxk sflkzc kksxbr nzlpn gfth zggxkc nnlg tmfgp jmpj brfpvc bvlksl snkk pzk vlfgsn pzmg vfs vxd qxctmd btfh bmvpz zcdcdf qndk hmm dztlx bzkfh ljzcbx kmvqht fnzgd kfjf kzmfh ppv jxdn ddnql ckrj kcj fllssz jvgxg hxltpq jnpbc pngbxj hlvl nlcqt pmjzb fxsxh hvgxt xgf lhnd dqbjj mpzz dxjdbh nhvx nnffp jfbvzd jrrqzc lkr mfmcgt fzmcnxjx fnpdz tpmkh hxbbn kgbzf fvvrc (contains wheat, dairy, eggs)
+fllssz rkgqk qlhm jxdn pzk rdn fgvhf jcfsd rmpf qjnqkj hchsm hxltpq kgbzf jccbbc jrdpn dcj kxzkbk vmnfl xbtfvdn dbjtns mzjhbl gmdxrp pzmg nkfjx lhnd mvzs hrrbkv ktqn xhlfkd rrbklsh nvhhp cdqqt rgxnd qpxhfp djffq kpsdtv hmm fcnbzf jvgxg dxftvrth ljzcbx jkbrhq xxrck rjqrpb stf pngbxj bvlksl jpcsh dnjjt dztlx sxbjr pmjzb mqls lnljt dqbjj jqvppk kbrdv tvxxn bzkfh nhvx fvvrc tmcql zzzgx bbljn xjkk qndk zggxkc xdzlvg fzmcnxjx xgqzlrd rrnhxk jfbvzd hlvl zkmbc ndvvpgr qgqqm pbbhtd prmglh snkk fdm nsmss (contains dairy, soy, eggs)
+dqbjj qndk hxltpq brfpvc mpzz zzzgx dcj qgqqm czvgtl fllssz rrbklsh nnrn dvkcq snkk jcfsd zbnv glnj kgbzf fvvrc qkkkvb zcdcdf lbxd llhzxnrz nlcqt kmvqht xzrn sfxmr tksln vfs nvhhp kpsdtv pcxfhk jpcsh ljzcbx sxvr szjdxh qjnqkj qpxhfp rrnhxk prs (contains shellfish, wheat)
+rrbklsh kgbzf fdm lhnd fhbldf rscln msczg fcnbzf jccbbc dxftvrth jzlflq xhlfkd hxltpq qjnqkj kxzkbk rvfhqbz lzmfqvz hxbbn nlcqt lkr szjdxh zcdcdf qpxhfp fvvrc dsghqp rblrbnhp btfh xzrn hdm sxvr hvgxt dcj xgf bnjmx tvxxn jkbrhq gfth rtct ztx kkxjgg vlfgsn pzmg brfpl ppv kbrdv xdzlvg smrks pmjzb brfpvc czvgtl svsq xbtfvdn dqbjj hblgrjgp jqvppk qjxbtlc dqnd zbnv nfjl xfrhjm nnrn jvgxg qndk kpsdtv pcjsl nzlpn hlvl (contains peanuts, eggs)
+jrdpn dsghqp xhlfkd jnpbc dqbjj sltqs fhbldf mzjhbl kcj ddnql cmmpcm mpzz tfbcbzz pzmg qkkkvb jkbrhq jvgxg dztlx nzp ktqn fgvhf nfjl kgbzf kxzkbk bmvpz ndvvpgr lzmfqvz bbljn zggxkc kpsdtv rdn fdm qpxhfp fllssz dqnd rkgqk hvgxt zcdcdf nhvx fztbgq fnpdz dcj rrbklsh tddgr nlcqt nnrn kbrdv vfs (contains soy, eggs, dairy)
+kbrdv vfs qjxbtlc tmcql jxdn rkgqk zggxkc sflkzc szjdxh fllssz pbbhtd nzp hchsm hrrbkv fnpdz rrnhxk ndvvpgr hdm dhqfbv dztlx bvlksl nnrn mpzz kmvqht fvvrc gfth xgf qpxhfp nhvx dbjtns rrbklsh kfjf pzmg xjkk prs hlfnt tfbcbzz rjqrpb llhzxnrz tmfgp jzlflq ppv tddgr xxrck cdqqt bmvpz rtct jvgxg xhlfkd skr xpjdsc kpsdtv tdkfbq brfpvc zcdcdf rdn vlfgsn ljzcbx czplkc fztbgq xfrhjm kgvmlg dqbjj ztx lgzmz (contains peanuts)
+hxltpq tmfgp pcxfhk dqbjj rtct xjkk fhbldf rmpf rblrbnhp fgvhf rbhjgg fllssz rhkxdmvz rdn tvxxn znnf svhqc nkfjx ccsxr dnjjt pzmg qjnqkj zcdcdf fztbgq xhlfkd nnffp svsq rvfhqbz znkx mqls kxddqq vxd qpxhfp nfjl kxzkbk ppv tpmkh jzlflq nlcqt kgbzf pcjsl bmvpz lmxrnmg xxrck vfs sltqs mfmcgt dxjdbh kpsdtv (contains nuts, dairy)
+krjt dqnd qlhm rrbklsh stf jmpj lmxrnmg xfrhjm nfjl kmvqht jrrqzc lnljt dxftvrth ppv djffq kpsdtv zcdcdf nnrn ktqn nnffp sltqs bvlksl tdkfbq fvvrc hdm jpcsh rrnhxk cdqqt jnpbc dqbjj jqvppk dvkcq znnf kgbzf tddgr fllssz fdm qpstz rhkxdmvz zggxkc jxmg pmjzb kbrdv pzmg zkmbc (contains eggs)
+gmdxrp kksxbr sltqs lnljt pbbhtd rdn zggxkc tdkfbq xgf xpjdsc cjxff trfmsz fzmcnxjx rbhjgg kcj dcj lmxrnmg gfth pngbxj jzlflq nsmss llhzxnrz bnjmx rjqrpb kmvqht jnpbc pzmg jhc nkfjx mvzs xhlfkd dnjjt jxmg btfh nzp lzmfqvz rmpf prs rtct vmnfl fvvrc tvxxn qxctmd jvgxg ztx zpmqcv tmcql rblrbnhp qpxhfp prmglh mpzz tfbcbzz dxftvrth msczg pcjsl vlfgsn nvhhp zmsh kgbzf cxbqtf qjxbtlc lhnd dqbjj qpstz czvgtl rscln dgc sfxmr znnf zcdcdf rgxnd tcl sflkzc ccsxr lgzmz fllssz tddgr (contains shellfish, eggs, dairy)
+nnrn fnpdz rjqrpb kxzkbk kxddqq ndvvpgr svsq jhc vxd xjkk dqbjj djffq zph nddjz pngbxj jfbvzd dztlx cxbqtf tmfgp pzk kpsdtv hxltpq fvvrc cjxff xgqzlrd lmxrnmg kfjf pzmg czvgtl mvzs gmdxrp sxvr zggxkc fllssz mqls kbrdv rblrbnhp kcj rvfhqbz kgbzf zcdcdf znnf rscln kkxjgg trfmsz nsmss jpcsh jmpj nzlpn jrrqzc rbhjgg (contains nuts)
+brfpvc lmxrnmg dxftvrth jpcsh rkgqk nkfjx zggxkc pmjzb nnffp nnrn krjt kqdk jxdn dztlx tvxxn djffq mctnbp fgvhf fxsxh czplkc jnpbc ppv hxltpq kgbzf xzrn pzmg szjdxh hxbbn fvvrc lkr xhlfkd gcmzg dbjtns dxjdbh kxzkbk rrbklsh kdggj tdkfbq trfmsz cmmpcm qkkkvb xpjdsc jzlflq dgc vxd dqbjj sxbjr kksxbr rhkxdmvz mpzz zcdcdf dvkcq hpnnf bmvpz znkx kmvqht jqvppk mfmcgt tpmkh lzmfqvz pngbxj sltqs fztbgq sflkzc rmpf cdqqt kpsdtv xxrck bnjmx nhvx kcj ztx fnpdz smrks znnf fllssz (contains sesame, peanuts)
+cmmpcm pzk gcmzg qpxhfp fvvrc dhqfbv pmjzb qgqqm xpjdsc hrrbkv rdn jcfsd pzmg slhjm qlhm kgbzf prs dsghqp lmxrnmg dqbjj hlfnt djffq nhvx mfmcgt dvkcq cxbqtf kxddqq xzrn kksxbr ckrj jfbvzd zcdcdf vmnfl xdzlvg hxbbn dxjdbh tcl ztx rkgqk brfpl kdggj kpsdtv smrks tpmkh kmvqht nzp jrdpn skr hvgxt ddnql pcxfhk lgzmz fxsxh jhc mzjhbl xgf rvfhqbz kfjf vxd bbljn lkr sltqs nnlg rtct kxzkbk msczg svsq tdkfbq czplkc pcjsl bzkfh rblrbnhp kcj tmcql mctnbp bnjmx (contains eggs, sesame)
+rkgqk znkx kzmfh fllssz cmmpcm fxsxh vxd kmvqht smrks kgbzf xjkk fnzgd jpcsh zpmqcv xgqzlrd nzlpn djffq pbbhtd svhqc kpsdtv dnjjt kkxjgg nkfjx snkk hmm czvgtl xxrck brfpl sfxmr hlfnt tmfgp pzmg zzzgx qpxhfp zrxk qlhm trfmsz dhqfbv dsghqp krjt dxjdbh dxftvrth rmpf zcdcdf qjnqkj sxvr rscln dqbjj gfth xgf dcj bnjmx lzmfqvz brfpvc qjxbtlc hblgrjgp kdggj hxbbn zggxkc jccbbc lmxrnmg fzmcnxjx jvgxg xhlfkd jrdpn fdm gmdxrp prmglh ljzcbx ccsxr (contains soy, nuts, peanuts)
+rmpf kdggj lhnd lzmfqvz lbxd dxftvrth xgf stf hmm hxltpq jfbvzd hdm pzmg jxmg mpzz rjqrpb fnpdz svhqc qgqqm fvvrc qpstz bnjmx ckrj nfjl qjnqkj jcfsd dnjjt bzbm lmxrnmg msczg pcxfhk tpmkh prs zggxkc szjdxh xpjdsc kgbzf zcdcdf rkgqk fllssz xhlfkd fcnbzf zph qpxhfp kpsdtv hpnnf cxbqtf xgqzlrd dsghqp (contains wheat, shellfish, eggs)
+dqbjj kgbzf bnjmx tfbcbzz sxbjr hlfnt rgxnd zcdcdf szjdxh vxd dqnd zkmbc fllssz hvgxt qlhm qkkkvb rrbklsh nnffp hblgrjgp qpxhfp dbjtns pzmg bzbm cjxff cdqqt kmvqht ktqn hxbbn tddgr kbrdv kxddqq ztx hxltpq zvvffr zpmqcv sxvr fvvrc nnrn lgzmz prmglh jcfsd pngbxj qxctmd mpzz lhnd xfrhjm vmnfl smrks vlfgsn hchsm ddnql fnzgd bbljn gmdxrp prs mvzs rdn (contains dairy, peanuts, soy)
+dgc tpmkh kzmfh czplkc jxdn kxddqq dqbjj jccbbc nnrn svhqc kfjf smrks skr nnlg djffq jnpbc trfmsz xjkk pcjsl qpxhfp svsq fvvrc vlfgsn ktqn cdqqt tcl zbnv fhbldf hxltpq ddnql zcdcdf pzmg brfpl jmpj rblrbnhp nfjl kxzkbk znkx xzrn ztx rhkxdmvz dcj bzbm qkkkvb nzlpn nhvx glnj zzzgx hchsm dztlx pbbhtd jzlflq zkmbc tksln hxbbn kksxbr qjxbtlc bmvpz kdggj jrrqzc gmdxrp kgbzf jfbvzd hvgxt dsghqp rbhjgg lkr rvfhqbz tfbcbzz mvzs tmfgp rtct dvkcq kgvmlg gcmzg lgzmz znnf fllssz tdkfbq slhjm (contains wheat, nuts)
+skr cmmpcm zzzgx kbrdv hxbbn fztbgq nzp prmglh dnjjt svhqc kpsdtv qpxhfp brfpl rvfhqbz mzjhbl stf fvvrc sxvr mfmcgt jxmg cjxff brfpvc szjdxh nlcqt ztx lbxd nzlpn tmfgp sfxmr kcj hlvl pzk dqbjj xgqzlrd qndk ccsxr ktqn dgc gcmzg czplkc jccbbc zbnv fcnbzf lmxrnmg qpstz fllssz tdkfbq hvgxt jzlflq nnrn kgvmlg cxbqtf nddjz zcdcdf gfth dztlx rtct kgbzf djffq hchsm (contains sesame)
+zpmqcv hvgxt tdkfbq fllssz tksln dqbjj slhjm tfbcbzz rmpf jpcsh pzmg zbnv hlvl jrdpn svhqc kxddqq zzzgx jrrqzc nnlg qkkkvb pcjsl dvkcq dcj kqdk qgqqm jzlflq kxzkbk lhnd kpsdtv fnpdz kksxbr dsghqp pngbxj kkxjgg zcdcdf skr llhzxnrz xgf qxctmd zkmbc zvvffr sflkzc kgbzf ccsxr jcfsd nzlpn kzmfh glnj brfpl fztbgq jkbrhq lnljt gcmzg bzkfh mfmcgt fhbldf nvhhp lmxrnmg jccbbc qpxhfp nddjz jqvppk rtct pbbhtd nlcqt ddnql rkgqk (contains sesame)
+hxbbn brfpvc dqbjj xfrhjm hchsm kkxjgg tdkfbq nzlpn vxd kdxmz hblgrjgp zggxkc sxbjr ppv pcxfhk dhqfbv rjqrpb mctnbp nlcqt nhvx zzzgx tksln jcfsd kxzkbk nzp dztlx ndvvpgr mvzs nnffp stf kgbzf ljzcbx fgvhf rbhjgg fdm cmmpcm qxctmd kqdk kksxbr znnf rrnhxk lgzmz ccsxr znkx jzlflq rtct hvgxt svsq ktqn qkkkvb zbnv tmfgp rgxnd zcdcdf qjnqkj fztbgq jkbrhq sltqs cjxff jrdpn rrbklsh fvvrc zmsh skr jpcsh cxbqtf nfjl rdn xzrn qpxhfp hlfnt fllssz zpmqcv nsmss mpzz nvhhp rscln xpjdsc jhc pzmg qlhm mzjhbl pbbhtd mfmcgt (contains shellfish, eggs, peanuts)
+lzmfqvz kcj jxmg ccsxr cdqqt rdn lgzmz jnpbc tcl kxzkbk tmcql qndk ppv tddgr ljzcbx btfh mctnbp dsghqp xgf jkbrhq bzbm jhc zcdcdf ckrj kgbzf jrdpn sxvr qpstz fhbldf tpmkh stf xpjdsc nkfjx nnffp qpxhfp hblgrjgp pzmg dqnd sxbjr hpnnf xdzlvg vxd djffq glnj dvkcq tmfgp vmnfl hvgxt fvvrc dxftvrth rbhjgg czplkc sflkzc rvfhqbz kpsdtv kksxbr xgqzlrd bmvpz ktqn rmpf rhkxdmvz dqbjj svsq (contains peanuts, sesame)
+brfpvc xhlfkd gcmzg gmdxrp fllssz zkmbc qgqqm ljzcbx tvxxn jvgxg kqdk lbxd dcj tmfgp dxjdbh zmsh dgc dnjjt dvkcq tcl pzmg vlfgsn qpxhfp kgbzf znkx sfxmr rkgqk dxftvrth kpsdtv mctnbp nnlg msczg dqbjj znnf sxbjr rrbklsh pngbxj zcdcdf ppv dbjtns jrrqzc lhnd bbljn jrdpn mvzs jzlflq ccsxr kksxbr jxdn ndvvpgr jkbrhq nsmss fnzgd (contains soy, sesame, peanuts)
+hchsm fvvrc cjxff sfxmr vlfgsn djffq qpxhfp tfbcbzz jxmg smrks ckrj lbxd kzmfh fxsxh sltqs zzzgx cxbqtf zmsh qjxbtlc nnffp kgbzf gcmzg fdm zpmqcv sxvr hdm jvgxg tvxxn hxltpq nddjz fztbgq kmvqht svsq qjnqkj nlcqt xxrck cdqqt fllssz pngbxj tmfgp xpjdsc tddgr xfrhjm kpsdtv szjdxh ztx mctnbp xbtfvdn lmxrnmg xgf pzmg dvkcq zcdcdf rjqrpb lzmfqvz tpmkh (contains eggs, dairy, sesame)
+zrxk kxzkbk bvlksl dxjdbh xjkk hlvl nfjl rmpf jqvppk kdxmz fnpdz dqnd hdm rhkxdmvz tdkfbq czplkc bmvpz fllssz djffq fxsxh nlcqt fhbldf btfh dqbjj brfpl xhlfkd jnpbc zggxkc ljzcbx szjdxh rbhjgg kkxjgg glnj fvvrc msczg zvvffr ztx jrrqzc ndvvpgr hxltpq prmglh pzmg sfxmr ccsxr zph fdm vfs cjxff zcdcdf zbnv svsq jxdn dgc tvxxn kqdk snkk kpsdtv nhvx kgbzf (contains nuts)
+jkbrhq brfpl rkgqk jzlflq znkx xdzlvg kpsdtv ljzcbx bvlksl kdggj mctnbp hxbbn qjnqkj ktqn kgbzf tmfgp ndvvpgr jvgxg nnrn qgqqm qjxbtlc fnzgd bzkfh zcdcdf hpnnf fnpdz hblgrjgp dhqfbv stf fzmcnxjx tdkfbq skr fllssz hlvl zzzgx czvgtl xxrck zpmqcv kfjf tmcql fvvrc fdm dztlx mzjhbl hmm svhqc mpzz jrdpn ccsxr qpxhfp sxbjr dxjdbh sltqs rtct msczg rhkxdmvz dxftvrth xgqzlrd trfmsz jqvppk kxzkbk qlhm zrxk qndk ztx pcxfhk nzlpn xjkk kdxmz dqnd glnj cdqqt zkmbc dgc kzmfh zggxkc dqbjj rbhjgg pzk (contains soy, shellfish, dairy)
+jnpbc fvvrc zcdcdf nnffp lzmfqvz hlvl nnrn czvgtl kgbzf dqbjj bzbm hrrbkv rrbklsh pmjzb fzmcnxjx hvgxt fllssz sxvr jrrqzc zbnv vmnfl fxsxh dxftvrth slhjm xhlfkd tdkfbq lbxd rdn brfpl kgvmlg cmmpcm nhvx mqls kcj rtct rkgqk tpmkh qgqqm lkr pngbxj cdqqt dztlx dbjtns rgxnd djffq ckrj xdzlvg kdggj jhc zvvffr mvzs mzjhbl tcl xjkk szjdxh cxbqtf pzmg dhqfbv bmvpz qpxhfp qlhm (contains wheat)
+bnjmx kpsdtv xzrn gcmzg llhzxnrz zzzgx zpmqcv dsghqp jrrqzc djffq rkgqk qpxhfp qkkkvb kbrdv vmnfl btfh rgxnd prs gmdxrp vfs pzmg fgvhf tvxxn mqls xbtfvdn xxrck trfmsz sxvr qndk kzmfh xgqzlrd fxsxh dxjdbh kmvqht mzjhbl jqvppk bvlksl pmjzb jrdpn kdxmz kdggj kgbzf mpzz lmxrnmg gfth ztx nvhhp zcdcdf hdm prmglh fvvrc ktqn bzkfh glnj tksln hblgrjgp pngbxj nnffp znkx fllssz czvgtl xdzlvg pcxfhk bzbm lkr (contains dairy, wheat, nuts)