diff options
Diffstat (limited to 'scratch/advent-of-code-2019/day_5.py')
-rw-r--r-- | scratch/advent-of-code-2019/day_5.py | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/scratch/advent-of-code-2019/day_5.py b/scratch/advent-of-code-2019/day_5.py new file mode 100644 index 000000000000..3d82846e6126 --- /dev/null +++ b/scratch/advent-of-code-2019/day_5.py @@ -0,0 +1,170 @@ +x = [ + 3, 225, 1, 225, 6, 6, 1100, 1, 238, 225, 104, 0, 1102, 31, 68, 225, 1001, + 13, 87, 224, 1001, 224, -118, 224, 4, 224, 102, 8, 223, 223, 1001, 224, 7, + 224, 1, 223, 224, 223, 1, 174, 110, 224, 1001, 224, -46, 224, 4, 224, 102, + 8, 223, 223, 101, 2, 224, 224, 1, 223, 224, 223, 1101, 13, 60, 224, 101, + -73, 224, 224, 4, 224, 102, 8, 223, 223, 101, 6, 224, 224, 1, 224, 223, + 223, 1101, 87, 72, 225, 101, 47, 84, 224, 101, -119, 224, 224, 4, 224, + 1002, 223, 8, 223, 1001, 224, 6, 224, 1, 223, 224, 223, 1101, 76, 31, 225, + 1102, 60, 43, 225, 1102, 45, 31, 225, 1102, 63, 9, 225, 2, 170, 122, 224, + 1001, 224, -486, 224, 4, 224, 102, 8, 223, 223, 101, 2, 224, 224, 1, 223, + 224, 223, 1102, 29, 17, 224, 101, -493, 224, 224, 4, 224, 102, 8, 223, 223, + 101, 1, 224, 224, 1, 223, 224, 223, 1102, 52, 54, 225, 1102, 27, 15, 225, + 102, 26, 113, 224, 1001, 224, -1560, 224, 4, 224, 102, 8, 223, 223, 101, 7, + 224, 224, 1, 223, 224, 223, 1002, 117, 81, 224, 101, -3645, 224, 224, 4, + 224, 1002, 223, 8, 223, 101, 6, 224, 224, 1, 223, 224, 223, 4, 223, 99, 0, + 0, 0, 677, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1105, 0, 99999, 1105, 227, 247, + 1105, 1, 99999, 1005, 227, 99999, 1005, 0, 256, 1105, 1, 99999, 1106, 227, + 99999, 1106, 0, 265, 1105, 1, 99999, 1006, 0, 99999, 1006, 227, 274, 1105, + 1, 99999, 1105, 1, 280, 1105, 1, 99999, 1, 225, 225, 225, 1101, 294, 0, 0, + 105, 1, 0, 1105, 1, 99999, 1106, 0, 300, 1105, 1, 99999, 1, 225, 225, 225, + 1101, 314, 0, 0, 106, 0, 0, 1105, 1, 99999, 8, 226, 677, 224, 102, 2, 223, + 223, 1005, 224, 329, 1001, 223, 1, 223, 1108, 677, 226, 224, 102, 2, 223, + 223, 1006, 224, 344, 101, 1, 223, 223, 108, 677, 226, 224, 102, 2, 223, + 223, 1006, 224, 359, 101, 1, 223, 223, 7, 677, 226, 224, 102, 2, 223, 223, + 1005, 224, 374, 101, 1, 223, 223, 1007, 226, 677, 224, 102, 2, 223, 223, + 1005, 224, 389, 101, 1, 223, 223, 8, 677, 677, 224, 102, 2, 223, 223, 1006, + 224, 404, 1001, 223, 1, 223, 1007, 677, 677, 224, 1002, 223, 2, 223, 1006, + 224, 419, 101, 1, 223, 223, 1108, 677, 677, 224, 1002, 223, 2, 223, 1005, + 224, 434, 1001, 223, 1, 223, 1107, 226, 677, 224, 102, 2, 223, 223, 1005, + 224, 449, 101, 1, 223, 223, 107, 226, 226, 224, 102, 2, 223, 223, 1006, + 224, 464, 101, 1, 223, 223, 1108, 226, 677, 224, 1002, 223, 2, 223, 1005, + 224, 479, 1001, 223, 1, 223, 7, 677, 677, 224, 102, 2, 223, 223, 1006, 224, + 494, 1001, 223, 1, 223, 1107, 677, 226, 224, 102, 2, 223, 223, 1005, 224, + 509, 101, 1, 223, 223, 107, 677, 677, 224, 1002, 223, 2, 223, 1006, 224, + 524, 101, 1, 223, 223, 1008, 677, 677, 224, 1002, 223, 2, 223, 1006, 224, + 539, 101, 1, 223, 223, 7, 226, 677, 224, 1002, 223, 2, 223, 1005, 224, 554, + 101, 1, 223, 223, 108, 226, 226, 224, 1002, 223, 2, 223, 1006, 224, 569, + 101, 1, 223, 223, 1008, 226, 677, 224, 102, 2, 223, 223, 1005, 224, 584, + 101, 1, 223, 223, 8, 677, 226, 224, 1002, 223, 2, 223, 1005, 224, 599, 101, + 1, 223, 223, 1007, 226, 226, 224, 1002, 223, 2, 223, 1005, 224, 614, 101, + 1, 223, 223, 1107, 226, 226, 224, 1002, 223, 2, 223, 1006, 224, 629, 101, + 1, 223, 223, 107, 677, 226, 224, 1002, 223, 2, 223, 1005, 224, 644, 1001, + 223, 1, 223, 1008, 226, 226, 224, 1002, 223, 2, 223, 1006, 224, 659, 101, + 1, 223, 223, 108, 677, 677, 224, 1002, 223, 2, 223, 1005, 224, 674, 1001, + 223, 1, 223, 4, 223, 99, 226 +] + +# Interpretter spec: +# Op-code width: 2 +# ABCDE +# A: Mode of 3rd parameter +# B: Mode of 2rd parameter +# C: Mode of 1st parameter +# DE: 2-digit op-code +# +# Not every op-code has the same arity. +# +# Parameter modes: +# - positional: index of memory. 0 +# - immediate: raw value. 1 +# Assert that you never attempt to write to an "immediate value" + +# Parameter modes +POS = '0' # positional parameter mode +VAL = '1' # immediate parameter mode + + +# Pasted from day-2.py +# interpretter :: Int -> [Int] -> [Int] -> IO () +def interpret(i, x, argv=[], outs=[]): + """Values in `argv` will be applied to any `input` fields.""" + # The widest op-code we'll see is 3 + 2 = 5 for either addition or + # multiplication since each of those is a 3-arity function with a two-digit + # op-code. + instruction = '{:05d}'.format(x[i]) + op = instruction[-2:] + + if op == '01': + a, b, out = x[i + 1], x[i + 2], x[i + 3] + mode_a, mode_b, mode_out = instruction[2], instruction[1], instruction[ + 0] + a = a if mode_a == VAL else x[a] + b = b if mode_b == VAL else x[b] + assert mode_out == POS + x[out] = a + b + return interpret(i + 4, x, argv=argv, outs=outs) + elif op == '02': + a, b, out = x[i + 1], x[i + 2], x[i + 3] + mode_a, mode_b, mode_out = instruction[2], instruction[1], instruction[ + 0] + a = a if mode_a == VAL else x[a] + b = b if mode_b == VAL else x[b] + assert mode_out == POS + x[out] = a * b + return interpret(i + 4, x, argv=argv, outs=outs) + # input + elif op == '03': + a = x[i + 1] + mode_a = instruction[2] + assert mode_a == POS + # What's the pythonic way to defensively get this value? + if len(argv) and argv[0] is not None: + x[a] = argv[0] + return interpret(i + 2, x, argv=argv[1:], outs=outs) + elif len(outs) and outs[-1] is not None: + x[a] = outs[-1] + return interpret(i + 2, x, argv=argv, outs=outs) + else: + # Here we want to block until the user applies input. This could be + # done easily with message passing for something similar. + x[a] = int(input('Enter: ')) + return interpret(i + 2, x, argv=argv) + # output + elif op == '04': + a = x[i + 1] + mode_a = instruction[2] + a = a if mode_a == VAL else x[a] + outs.append(a) + return interpret(i + 2, x, argv=argv, outs=outs) + # jump-if-true + elif op == '05': + a, b = x[i + 1], x[i + 2] + mode_a, mode_b = instruction[2], instruction[1] + a = a if mode_a == VAL else x[a] + b = b if mode_b == VAL else x[b] + if a != 0: + return interpret(b, x, argv=argv, outs=outs) + else: + return interpret(i + 3, x, argv=argv, outs=outs) + # jump-if-false + elif op == '06': + a, b = x[i + 1], x[i + 2] + mode_a, mode_b = instruction[2], instruction[1] + a = a if mode_a == VAL else x[a] + b = b if mode_b == VAL else x[b] + if a == 0: + return interpret(b, x, argv=argv, outs=outs) + else: + return interpret(i + 3, x, argv=argv, outs=outs) + pass + # less than + elif op == '07': + a, b, out = x[i + 1], x[i + 2], x[i + 3] + mode_a, mode_b, mode_out = instruction[2], instruction[1], instruction[ + 0] + a = a if mode_a == VAL else x[a] + b = b if mode_b == VAL else x[b] + assert mode_out == POS + if a < b: + x[out] = 1 + else: + x[out] = 0 + return interpret(i + 4, x, argv=argv, outs=outs) + # equals + elif op == '08': + a, b, out = x[i + 1], x[i + 2], x[i + 3] + mode_a, mode_b, mode_out = instruction[2], instruction[1], instruction[ + 0] + a = a if mode_a == VAL else x[a] + b = b if mode_b == VAL else x[b] + assert mode_out == POS + if a == b: + x[out] = 1 + else: + x[out] = 0 + return interpret(i + 4, x, argv=argv, outs=outs) + elif op == '99': + return x[0] + else: + raise Exception('Unsupported opcode: {}.'.format(op)) |