Author: Honza Pokorny <me@honza.ca>
7p2
007/main.py | 81 ++++++++++++++++++++++++++++++++++++++----------------
diff --git a/007/main.py b/007/main.py index 97d373b878212f1cf602b920f1c5f30fce796f5f..8372b7d4ea77ed2c0a6ed13fc0a04c6ba7596020 100644 --- a/007/main.py +++ b/007/main.py @@ -5,6 +5,8 @@ opcode = re.compile(r'(\d{2})') OPS = ['01', '02', '03', '04', '99'] +NEEDS_INPUT = 'NI' +HALT = 'H' def rev(s): @@ -29,13 +31,12 @@ def mult(a, b): return a * b -def intcode(input_list, *input_codes): +def intcode(input_list, *input_codes, cur=0): 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 @@ -95,6 +96,15 @@ cur += 4 continue if op == '03': + + if not input_codes: + return { + 'output': outputs, + 'state': NEEDS_INPUT, + 'memory': input_list, + 'cur': cur, + } + input_list[input_list[cur + 1]] = input_codes.pop() cur += 2 continue @@ -193,30 +203,56 @@ cur += 4 continue - return outputs + return { + 'output': outputs, + 'state': HALT, + 'memory': input_list, + 'cur': None + } def run_phases(input_list, phases): prog_input = 0 + cur = 0 - for phase in phases: - out = intcode(input_list, phase, prog_input) + state = {} + + while True: + for p in itertools.repeat(phases): + for i in phases: + amplifier_state = state.get(i, { + 'memory': copy.deepcopy(input_list), + 'cur': 0, + 'state': None + }) + + if not amplifier_state['state']: + inputs = [i, prog_input] + else: + inputs = [prog_input] + + out = intcode(amplifier_state['memory'], + *inputs, + cur=amplifier_state['cur']) - if not len(out): - raise Exception('no out') + if out['state'] == HALT: + if i == phases[-1]: + return out['output'][0] - prog_input = out[0] + state[i] = out + prog_input = out['output'][0] - return prog_input + if prog_input > 1000000000000: + raise Exception('too much') def find_solution(input_list): max_v = 0 max_perm = None - for v in itertools.permutations('01234'): + for v in itertools.permutations('56789'): phases = list(map(int, list(v))) - prog_out = run_phases(input_list, phases) + prog_out = run_phases(copy.deepcopy(input_list), phases) if prog_out > max_v: max_v = prog_out @@ -232,22 +268,20 @@ 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,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26, 27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5], + [9,8,7,6,5], + 139629729 ), ( - [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,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54, + -5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4, + 53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10 + ], + [9,7,8,5,6], + 18216 ), - - ( - [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 - ) ] @@ -260,7 +294,6 @@ # actual_phase, actual_value = find_solution(input_list) # print(actual_phase, expected_phase) # print(actual_value, expected_value) # print('') - print(find_solution(puzzle_input)) if __name__ == '__main__':