aoc

commit 05b6fac1c9019aa6c3c85e155b2bb8f050de177d

Author: Honza Pokorny <me@honza.ca>

working 7p1

 007/main.py | 262 +++++++++++++++++++++++++++++++++++++++++++++++++++++++


diff --git a/007/main.py b/007/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..a714181fecaa6751a60906d0a3439065934ab64a
--- /dev/null
+++ b/007/main.py
@@ -0,0 +1,262 @@
+import re
+import copy
+import itertools
+
+opcode = re.compile(r'(\d{2})')
+
+OPS = ['01', '02', '03', '04', '99']
+
+
+def rev(s):
+    r = []
+    for l in s:
+        r.append(l)
+
+    r.reverse()
+    return ''.join(r)
+
+
+
+class NonHaltException(Exception):
+    pass
+
+
+def add(a, b):
+    return a + b
+
+
+def mult(a, b):
+    return a * b
+
+
+def intcode(input_list, *input_codes):
+    input_codes = list(input_codes)
+    input_codes.reverse()
+
+    outputs = []
+
+    cur = 0
+    # if input_list[0] == 3:
+    #     input_list[input_list[1]] = input_codes.pop()
+    #     cur += 2
+
+    while True:
+        op_value = input_list[cur]
+        op_value_string = '000000' + str(op_value)
+
+        op = op_value_string[-2:]
+
+        front = op_value_string[0:-2]
+        front = rev(front)
+
+        if op == '99':
+            break
+
+        if op == '01':
+            # 0 po, like before
+            # 1 im
+            a_mode = front[0]
+            b_mode = front[1]
+
+            if a_mode == '0':
+                a = input_list[input_list[cur + 1]]
+            else:
+                a = input_list[cur + 1]
+
+            if b_mode == '0':
+                b = input_list[input_list[cur + 2]]
+            else:
+                b = input_list[cur + 2]
+
+            result_pos = input_list[cur + 3]
+            input_list[result_pos] = add(a, b)
+            cur += 4
+            continue
+
+        if op == '02':
+            # 0 po, like before
+            # 1 im
+            a_mode = front[0]
+            b_mode = front[1]
+
+            if a_mode == '0':
+                a = input_list[input_list[cur + 1]]
+            else:
+                a = input_list[cur + 1]
+
+            if b_mode == '0':
+                b = input_list[input_list[cur + 2]]
+            else:
+                b = input_list[cur + 2]
+
+            result_pos = input_list[cur + 3]
+            input_list[result_pos] = mult(a, b)
+            cur += 4
+            continue
+
+        if op == '03':
+            input_list[input_list[cur + 1]] = input_codes.pop()
+            cur += 2
+            continue
+
+        if op == '04':
+            mode = front[0]
+            if mode == '0':
+                o = input_list[input_list[cur + 1]]
+            else:
+                o = input_list[cur + 1]
+            outputs.append(o)
+            cur += 2
+            continue
+
+        if op == '05':
+            mode = front[0]
+            if mode == '0':
+                v = input_list[input_list[cur + 1]]
+            else:
+                v = input_list[cur + 1]
+
+            if v is not 0:
+                m2 = front[1]
+                if m2 == '0':
+                    cur = input_list[input_list[cur + 2]]
+                else:
+                    cur = input_list[cur + 2]
+            else:
+                cur += 3
+
+        if op == '06':
+            mode = front[0]
+            if mode == '0':
+                v = input_list[input_list[cur + 1]]
+            else:
+                v = input_list[cur + 1]
+
+            if v == 0:
+                m2 = front[1]
+                if m2 == '0':
+                    cur = input_list[input_list[cur + 2]]
+                else:
+                    cur = input_list[cur + 2]
+            else:
+                cur += 3
+
+        if op == '07':
+            # 0 po, like before
+            # 1 im
+            a_mode = front[0]
+            b_mode = front[1]
+
+            if a_mode == '0':
+                a = input_list[input_list[cur + 1]]
+            else:
+                a = input_list[cur + 1]
+
+            if b_mode == '0':
+                b = input_list[input_list[cur + 2]]
+            else:
+                b = input_list[cur + 2]
+
+            result_pos = input_list[cur + 3]
+
+            if a < b:
+                input_list[result_pos] = 1
+            else:
+                input_list[result_pos] = 0
+
+            cur += 4
+            continue
+
+        if op == '08':
+            # 0 po, like before
+            # 1 im
+            a_mode = front[0]
+            b_mode = front[1]
+
+            if a_mode == '0':
+                a = input_list[input_list[cur + 1]]
+            else:
+                a = input_list[cur + 1]
+
+            if b_mode == '0':
+                b = input_list[input_list[cur + 2]]
+            else:
+                b = input_list[cur + 2]
+
+            result_pos = input_list[cur + 3]
+
+            if a == b:
+                input_list[result_pos] = 1
+            else:
+                input_list[result_pos] = 0
+
+            cur += 4
+            continue
+
+    return outputs
+
+
+def run_phases(input_list, phases):
+    prog_input = 0
+
+    for phase in phases:
+        out = intcode(input_list, phase, prog_input)
+
+        if not len(out):
+            raise Exception('no out')
+
+        prog_input = out[0]
+
+    return prog_input
+
+
+def find_solution(input_list):
+    max_v = 0
+    max_perm = None
+
+    for v in itertools.permutations('01234'):
+        phases = list(map(int, list(v)))
+        prog_out = run_phases(input_list, phases)
+
+        if prog_out > max_v:
+            max_v = prog_out
+            max_perm = v
+
+    if not max_perm:
+        max_perm = []
+
+    return list(map(int, max_perm)), max_v
+
+
+
+def main():
+    inputs = [
+        (
+           [3,15,3,16,1002,16,10,16,1,16,15,15,4,15,99,0,0],
+            [4,3,2,1,0],
+            43210
+        ),
+
+        (
+            [3,23,3,24,1002,24,10,24,1002,23,-1,23, 101,5,23,23,1,24,23,23,4,23,99,0,0],
+            [0,1,2,3,4],
+            54321
+        ),
+
+        (
+            [3,31,3,32,1002,32,10,32,1001,31,-2,31,1007,31,0,33,1002,33,7,33,1,33,31,31,1,32,31,31,4,31,99,0,0,0],
+            [1,0,4,3,2],
+            65210
+        )
+
+    ]
+
+    for input_list, expected_phase, expected_value in inputs:
+        actual_phase, actual_value = find_solution(input_list)
+        print(actual_phase, expected_phase)
+        print(actual_value, expected_value)
+        print('')
+
+
+if __name__ == '__main__':
+    main()