My Advent of Code solutions in Python. kevinyap.ca/2019/12/going-fast-in-advent-of-code/
advent-of-code python
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 105 lines 2.7 kB view raw
1import fileinput 2from itertools import permutations 3 4 5def parse_mode(tape, mode_op, a, b, c): 6 op = mode_op % 100 7 mode_a = (mode_op // 100) % 10 8 mode_b = (mode_op // 1000) % 10 9 mode_c = (mode_op // 10000) % 10 10 11 return op, mode_a, mode_b, mode_c 12 13 14GLOBAL_INPUTS = [0, 0, 0, 0, 0] 15 16 17def emulate(phase, amp_num, pc=0): 18 tape = TAPE[:] 19 outs = [] 20 read_phase = False 21 22 while pc < len(tape): 23 mode_op, a, b, c = tape[pc:pc+4] 24 op, mode_a, mode_b, mode_c = parse_mode(tape, mode_op, a, b, c) 25 modes = [mode_a, mode_b, mode_c] 26 last_pc = pc 27 28 # ADD a b c 29 if op == 1: 30 tape[c] = (a if mode_a else tape[a]) + (b if mode_b else tape[b]) 31 pc += 4 32 33 # MUL a b c 34 elif op == 2: 35 tape[c] = (a if mode_a else tape[a]) * (b if mode_b else tape[b]) 36 pc += 4 37 38 # INP a 39 elif op == 3: 40 if read_phase: 41 tape[a] = GLOBAL_INPUTS[amp_num] 42 else: 43 tape[a] = phase 44 read_phase = True 45 pc += 2 46 47 # OUT b 48 elif op == 4: 49 outs.append(a if mode_a else tape[a]) 50 yield a if mode_a else tape[a] 51 pc += 2 52 53 # JZ a b 54 elif op == 5: 55 if (a if mode_a else tape[a]) != 0: 56 pc = (b if mode_b else tape[b]) 57 else: 58 pc += 3 59 60 # JNZ a b 61 elif op == 6: 62 if (a if mode_a else tape[a]) == 0: 63 pc = (b if mode_b else tape[b]) 64 else: 65 pc += 3 66 67 # LT a b c 68 elif op == 7: 69 tape[c] = 1 if (a if mode_a else tape[a]) < (b if mode_b else tape[b]) else 0 70 pc += 4 71 72 # EQ a b c 73 elif op == 8: 74 tape[c] = 1 if (a if mode_a else tape[a]) == (b if mode_b else tape[b]) else 0 75 pc += 4 76 77 # HALT 78 elif op == 99: 79 raise StopIteration() 80 81 82def emulate_sequence(phases): 83 global GLOBAL_INPUTS 84 GLOBAL_INPUTS = [0] * 5 85 amps = [emulate(phases[i], i) for i in range(5)] 86 inp = 0 87 on_amp = 0 88 last_output = 0 89 90 try: 91 while True: 92 inp = next(amps[on_amp]) 93 last_output = inp 94 on_amp = (on_amp + 1) % 5 95 GLOBAL_INPUTS[on_amp] = inp 96 except StopIteration: 97 return last_output 98 99 100# Read input 101TAPE = [int(x) for x in fileinput.input()[0].split(',')] 102TAPE += [None, None, None, None] 103 104print "Part 1:", max(emulate_sequence(p) for p in permutations(range(5), 5)) 105print "Part 2:", max(emulate_sequence(p) for p in permutations(range(5, 10), 5))