Frans Bergman 3 лет назад
Родитель
Сommit
22474d6679
3 измененных файлов с 442 добавлено и 0 удалено
  1. 252 0
      24.input
  2. 186 0
      24.py
  3. 4 0
      24.small.input

+ 252 - 0
24.input

@@ -0,0 +1,252 @@
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 10
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 12
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 10
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 10
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 12
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 8
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 11
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 4
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x 0
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 3
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 15
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 10
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 13
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 6
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -12
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 13
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -15
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 8
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -15
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 1
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -4
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 7
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 1
+add x 10
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 6
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -5
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 9
+mul y x
+add z y
+inp w
+mul x 0
+add x z
+mod x 26
+div z 26
+add x -12
+eql x w
+eql x 0
+mul y 0
+add y 25
+mul y x
+add y 1
+mul z y
+mul y 0
+add y w
+add y 9
+mul y x
+add z y

+ 186 - 0
24.py

@@ -0,0 +1,186 @@
+from copy import deepcopy
+from math import floor
+from itertools import product
+from util import get_input
+
+input = get_input("24.input")
+
+# Yes, you have to adjust these manually.
+# Yes, it can be done automatically.
+# No, I don't want to.
+#                  1111
+#        01234567890123
+part1 = "93959993429899"
+part2 = "11815671117121"
+
+lookup = {k: int(part2[k]) for k in range(14)}
+
+def paren(exp):
+    return "(" + exp + ")"
+
+def pprint(exp):
+    if exp[0] == 'c':
+        return str(exp[1])
+    elif exp[0] == 'in':
+        return 'in' + str(exp[1])
+    elif exp[0] == 'add':
+        return paren(pprint(exp[1]) + ' + ' + pprint(exp[2]))
+    elif exp[0] == 'mul':
+        return paren(pprint(exp[1]) + ' * ' + pprint(exp[2]))
+    elif exp[0] == 'div':
+        return paren(pprint(exp[1]) + ' / ' + pprint(exp[2]))
+    elif exp[0] == 'mod':
+        return paren(pprint(exp[1]) + ' % ' + pprint(exp[2]))
+    elif exp[0] == 'eql':
+        return paren(pprint(exp[1]) + ' == ' + pprint(exp[2]))
+    elif exp[0] == 'sum':
+        return paren(" + ".join(pprint(t) for t in exp[1]))
+    raise Exception("Not allowed: {}".format(exp[0]))
+
+def evl(exp, lookup):
+    if exp[0] == 'c':
+        return exp[1]
+    elif exp[0] == 'in':
+        return lookup[exp[1]]
+    elif exp[0] == 'add':
+        return evl(exp[1], lookup) + evl(exp[2], lookup)
+    elif exp[0] == 'mul':
+        return evl(exp[1], lookup) * evl(exp[2], lookup)
+    elif exp[0] == 'div':
+        return floor(evl(exp[1], lookup) / evl(exp[2], lookup))
+    elif exp[0] == 'mod':
+        return evl(exp[1], lookup) % evl(exp[2], lookup)
+    elif exp[0] == 'eql':
+        return 1 if evl(exp[1], lookup) == evl(exp[2], lookup) else 0
+    elif exp[0] == 'sum':
+        return sum(evl(t, lookup) for t in exp[1])
+    raise Exception("Not allowed: {}".format(exp[0]))
+
+def max_val(exp, minv=False):
+    if exp[0] == 'c':
+        return exp[1]
+    elif exp[0] == 'in':
+        return 1 if minv else 9
+    elif exp[0] == 'add':
+        return max_val(exp[1], minv) + max_val(exp[2], minv)
+    elif exp[0] == 'mul':
+        return max_val(exp[1], minv) * max_val(exp[2], minv)
+    elif exp[0] == 'div':
+        return floor(max_val(exp[1], minv) / max_val(exp[2], not minv))
+    elif exp[0] == 'mod':
+        return (max_val(exp[2]) - 1) if not minv else 0
+    elif exp[0] == 'eql':
+        return 0 if minv else 1
+    elif exp[0] == 'sum':
+        return sum(max_val(t, minv) for t in exp[1])
+    raise Exception("Not allowed: {}".format(exp[0]))
+
+def reduce_sum(terms):
+    indices = [i for (i, t) in enumerate(terms) if t[0] == 'c']
+    if len(indices) == 2:
+        terms[indices[0]] = ('c', terms[indices[0]][1] + terms[indices[1]][1])
+        terms.pop(indices[1])
+    return [t for t in terms if t != ('c', 0)]
+
+def simplify(exp):
+    global lookup
+    if exp[0] == 'sum':
+        s = reduce_sum([simplify(t) for t in exp[1]])
+        if len(s) == 1:
+            return s[0]
+        else:
+            return ('sum', s)
+    elif exp[0] == 'add':
+        if exp[1][0] == 'sum' and exp[2][0] == 'sum':
+            return simplify(('sum', exp[1][1] + exp[2][1]))
+        elif exp[1][0] == 'sum':
+            return simplify(('sum', exp[1][1] + [exp[2]]))
+        elif exp[2][0] == 'sum':
+            return simplify(('sum', [exp[1]] + exp[2][1]))
+        else:
+            return simplify(('sum', [exp[1], exp[2]]))
+    elif exp[0] == 'mul':
+        if exp[2] == ('c', 0) or exp[1] == ('c', 0):
+            return ('c', 0)
+        if exp[2] == ('c', 1):
+            return exp[1]
+        if exp[1] == ('c', 1):
+            return exp[2]
+        if exp[1][0] == 'div' and exp[1][2] == exp[2]:
+            return exp[1][1]
+        if exp[1][0] == 'c' and exp[2][0] == 'c':
+            return ('c', exp[1][1] * exp[2][1])
+    elif exp[0] == 'div':
+        if exp[2] == ('c', 1):
+            return exp[1]
+        if exp[1][0] == 'c' and exp[2][0] == 'c':
+            return ('c', floor(exp[1][1] / exp[2][1]))
+        if exp[2][0] == 'c' and max_val(exp[1]) < exp[2][1]:
+            return ('c', 0)
+        if exp[1][0] == 'mul' and exp[1][2] == exp[2]:
+            return exp[1][1]
+        if exp[1][0] == 'sum':
+            indices = [i for i, t in enumerate(exp[1][1]) if t[0] == 'mul' and t[2] == exp[2]]
+            if len(indices) > 0:
+                terms = exp[1][1]
+                term = terms[indices[0]][1]
+                terms.pop(indices[0])
+                return simplify(('sum', [term] + [('div', ('sum', terms), exp[2])]))
+    elif exp[0] == 'mod':
+        if exp[1][0] == 'c' and exp[2][0] == 'c':
+            return ('c', exp[1][1] % exp[2][1])
+        if exp[2][0] == 'c' and max_val(exp[1]) < exp[2][1]:
+            return exp[1]
+        if exp[1][0] == 'mul' and exp[1][1] == exp[2]:
+            return ('c', 0)
+        if exp[1][0] == 'mul' and exp[1][2] == exp[2]:
+            return ('c', 0)
+        if exp[1][0] == 'sum':
+            return simplify(('sum', [('mod', t, exp[2]) for t in exp[1][1] if not (t[0] == 'mul' and t[2] == exp[2])]))
+    elif exp[0] == 'eql':
+        if exp[1] == exp[2]:
+            return ('c', 1)
+        try:
+            if evl(exp[1], lookup) == evl(exp[2], lookup):
+                print(pprint(exp[1]), 'EQUALS', pprint(exp[2]))
+                return ('c', 1)
+        except KeyError:
+            pass
+        if max_val(exp[1]) < max_val(exp[2], True):
+            #print("1Reduced", pprint(exp[1]), "<>", pprint(exp[2]))
+            return ('c', 0)
+        if max_val(exp[2]) < max_val(exp[1], True):
+            #print("2Reduced", pprint(exp[1]), "<>", pprint(exp[2]))
+            return ('c', 0)
+    #print(pprint(exp))
+    return exp
+
+def run(input):
+    var = {
+            'x': ("c", 0),
+            'y': ("c", 0),
+            'z': ("c", 0),
+            'w': ("c", 0),
+            }
+    input_idx = 0
+    for i, line in enumerate(input[:270]):
+        #print(i + 1, "/", len(input))
+        l = line.split()
+        if l[0] == 'inp':
+            var[l[1]] = ("in", input_idx)
+            input_idx += 1
+        else:
+            try:
+                val = ("c", int(l[2]))
+            except ValueError:
+                val = var[l[2]]
+            var[l[1]] = simplify((l[0], deepcopy(var[l[1]]), deepcopy(val)))
+    print(pprint(var['z']).replace("*", "*\n"))
+    print(max_val(var['z'], True))
+    print(evl(var['z'], lookup))
+    #print(max_val(var['z']))
+
+run(input)
+
+print("Part 1:", part1)
+print("Part 2:", part2)

+ 4 - 0
24.small.input

@@ -0,0 +1,4 @@
+inp z
+inp x
+mul z 3
+eql z x