def run_amps_feedback(memory, preset: list): amplifierA = ic.IntCode('A', memory, [preset[0]]) amplifierB = ic.IntCode('B', memory, [preset[1]]) amplifierC = ic.IntCode('C', memory, [preset[2]]) amplifierD = ic.IntCode('D', memory, [preset[3]]) amplifierE = ic.IntCode('E', memory, [preset[4]]) amp_list = [amplifierA, amplifierB, amplifierC, amplifierD, amplifierE] # Initialize all 5 amplifiers by feeding them their phase codes and jumping them amp_list[0].executeIntCode() amp_list[1].executeIntCode() amp_list[2].executeIntCode() amp_list[3].executeIntCode() amp_list[4].executeIntCode() amplifiers_cycle = cycle(amp_list) amplitude = 0 # Primary amplification loop for amp in amplifiers_cycle: if amp.mem[amp.pointerAddress] == 99: break amp.writeRam(amplitude) amp.executeIntCode() amplitude = amp.readRam() return amplitude
def test_samples(self): """Test Intcode object with samples from problem description""" # 1. 1,0,0,0,99 becomes 2,0,0,0,99 (1 + 1 = 2) mycode = intcode.IntCode(text='1,0,0,0,99') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.positions, [2, 0, 0, 0, 99]) # 2. 2,3,0,3,99 becomes 2,3,0,6,99 (3 * 2 = 6) mycode = intcode.IntCode(text='2,3,0,3,99') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.positions, [2, 3, 0, 6, 99]) # 3. 2,4,4,5,99,0 becomes 2,4,4,5,99,9801 (99 * 99 = 9801) mycode = intcode.IntCode(text='2,4,4,5,99,0') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.positions, [2, 4, 4, 5, 99, 9801]) # 4. 1,1,1,4,99,5,6,0,99 becomes 30,1,1,4,2,5,6,0,99 mycode = intcode.IntCode(text='1,1,1,4,99,5,6,0,99') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.positions, [30, 1, 1, 4, 2, 5, 6, 0, 99]) # 5. 1,9,10,3,2,3,11,0,99,30,40,50 becomes 3500,9,10,70,2,3,11,0,99,30,40,50 mycode = intcode.IntCode(text='1,9,10,3,2,3,11,0,99,30,40,50') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.positions, [3500, 9, 10, 70, 2, 3, 11, 0, 99, 30, 40, 50])
def part2(filename): with open(filename) as f: inputs = list(map(int, f.readline().split(','))) perms = list(permutations(range(5, 10))) hsignal = 0 for perm in perms: ic0 = intcode.IntCode(list(inputs), 0, 0) ic0.process([perm[0], 0]) ic1 = intcode.IntCode(list(inputs), 0, 0) ic1.process([perm[1]] + ic0.outputs) ic2 = intcode.IntCode(list(inputs), 0, 0) ic2.process([perm[2]] + ic1.outputs) ic3 = intcode.IntCode(list(inputs), 0, 0) ic3.process([perm[3]] + ic2.outputs) ic4 = intcode.IntCode(list(inputs), 0, 0) ic4.process([perm[4]] + ic3.outputs) while True: if ic4.completed: if hsignal < ic4.outputs[-1]: hsignal = ic4.outputs[-1] break ic0.resume() ic0.process(ic4.outputs) ic1.resume() ic1.process(ic0.outputs) ic2.resume() ic2.process(ic1.outputs) ic3.resume() ic3.process(ic2.outputs) ic4.resume() ic4.process(ic3.outputs) print(f"part2 >>> highest signal for thrusters {hsignal}")
def __init__(self, prog, h, w): self.computer = intcode.IntCode(prog) self.screen = [[0 for i in range(w)] for i in range(h)] self.score = 0 self.game_over = False self.init = True self.paddle_x = 0
def __init__(self, prog): self.direction = 0 self.outputs = [0, 0] self.brain = intcode.IntCode(prog, [1 for i in range(100)]) self.white = set() self.black = set() self.loc = (0, 0)
def fb_run(self, phase=0, inp=0): "Return the status and output of running the amplifier with inputs phase and inp" # 1. Create a computer with the program from text (if not already created) if self.computer is None: self.computer = intcode.IntCode(text=self.text) inp = [phase, inp] else: inp = [inp] # 3. Run the computer with inputs #print("Running computer with input = %s, counter=%s" % (inp, self.computer.counter)) result = self.computer.run(inp=inp) # 4. Make sure it ended with a halt instruction or input instruction if result not in (intcode.STOP_HLT, intcode.STOP_INP): print("amplifier %s input=%s ended with %d" % (self.letter, inp, result)) return None # 5. Return the result and output output = self.computer.outputs() if len(output) != 1: print("amplifier %s input=%s ended produced %d outputs" % (self.letter, inp, len(output))) return None return (result, output[0])
def main(): with open("input.txt") as f: content = f.read() program = list(map(lambda x: int(x), content.split(","))) computer = intcode.IntCode(intcode.InputProvider(), intcode.OutputSink()) computer.run_to_completion(program)
def check_loc(self, col, row): "Check a location, dispathing a drone if necessary" # 1. If we already know what happens at a location, just return it if (col, row) in self.beam_map: #print("(%d,%d) already mapped as %d" % (col, row, self.beam_map[(col, row)])) return self.beam_map[(col, row)] # 2. Build a new drone #print("Building a drone to check (%d,%d)" % (col, row)) uav = intcode.IntCode(text=self.program) self.drones += 1 # 3. Run the drone with this input result = uav.run(inp=([col, row])) if result != intcode.STOP_HLT: print("drone stopped with %d for (%d,%d)" % (result, col, row)) return 0 # 4. Get the beam effect at this point output = uav.outputs()[0] # 5. Record the output self.beam_map[(col, row)] = output self.points += output # 6. Return output (0 if no beam, 1 if beam) return output
def test_challenge_coin(self): """Test Intcode with the 2019 Advent of Code Novetta challenge coin""" mycode = intcode.IntCode(text='9,7,20201,0,31,0,4,30,101,-1,7,7,109,-1,1206,0,31,1005,8,2,0,16,16,12,-33,-34,2,8,6,-23,-64,99') self.assertEqual(mycode.run(), intcode.STOP_HLT) out = mycode.outputs() self.assertEqual(out, [35, 76, 105, 107, 101, 65, 66, 111, 115, 115]) self.assertEqual(''.join([chr(_) for _ in out]), '#LikeABoss')
def __init__(self, prog): self.brain = intcode.IntCode(prog) self.done = False self.loc = (0, 0) self.traversed = set() self.wall = set() self.shortest_path_traversed = set()
def amp_thread(n, a): nonlocal inputs nonlocal results mach = intcode.IntCode(program) inpos = 0 next = (n + 1) % 5 def input_fn(): nonlocal inpos nonlocal conds # print(f'Mach {n} asking for input') with conds[n]: if inpos >= len(inputs[n]): conds[n].wait() val = inputs[n][inpos] inpos += 1 # print(f'Mach {n} getting input {val}') return val def output_fn(v): nonlocal inputs # print(f'Mach {n} producing output {v}') with conds[next]: inputs[next] += [v] conds[next].notify() mach.run(input_fn, output_fn) results[n] = mach.output[-1]
def part_one(args, input_lines): "Process part one of the puzzle" # 1. Create the computer computer = intcode.IntCode(text=input_lines[0]) # 2. Get the maximum of the amplifiers without feedback halted = computer.run(watch=args.verbose, inp=[1]) if halted != intcode.STOP_HLT: print("Computer stopped unexpectively, reason = %d" % (halted)) solution = None else: solution = computer.outputs() if len(solution) == 0: print("No output") solution = None elif len(solution) > 1: print("Problems with opcodes %s" % (solution)) solution = None else: print("BOOST keycode = %d" % (solution[0])) if not solution: print("Unable to determine best output") # 3. Return result return solution is not None
def try_settings_part2(self, settings): connections = [] for i in range(0, 5): connection = AmpConnection("Amp" + str(i)) connection.queue.append(settings[i]) connections.append(connection) connections[0].queue.append(0) computers = [] for i in range(0, 5): inputConnection = connections[i] if i + 1 < len(connections): outputConnection = connections[i + 1] else: outputConnection = connections[0] print( f"Connecting computer '{i}, input: '{inputConnection.name}', output: '{outputConnection.name}'" ) computer = intcode.IntCode(inputConnection, outputConnection) computers.append(computer) threads = [] for c in computers: threads.append(ComputerThread(c, self.program)) for t in threads: t.start() for t in threads: t.join() return connections[0].queue.pop()
def test_2(self): input = [1102, 34915192, 34915192, 7, 4, 7, 99, 0] output_sink = TestOutputSink() computer = intcode.IntCode(TestInputProvider(0), output_sink) computer.run_to_completion(input) strOutput = str(output_sink.output[0]) self.assertEqual(16, len(strOutput))
def part2(filename): with open(filename) as f: inputs = [int(l) for l in f.readline().split(',')] # expand the list of inputs because to avoid index-out-of-range inputs.extend([0]*1000) ic = intcode.IntCode(list(inputs), 0, 0) p = Point(0, 0) panels = {p: White} d = Directions[0] while not ic.completed: c = panels[p] if p in panels else Black ic.process([c]) panels[p] = ic.outputs[0] dix = (d + 3) % 4 if ic.outputs[1] == Black else (d + 1) % 4 d = Directions[dix] p = movpoint(p, d) ic.resume() mx = abs(list(map(max, zip(*panels.keys())))[0])+1 my = abs(list(map(min, zip(*panels.keys())))[1])+1 screen = [[0 for x in range(mx)] for y in range(my)] for (x, y), v in panels.items(): screen[abs(y)][abs(x)] = v [print(' '.join([' ' if i == 0 else '#' for i in line])) for line in screen]
def part_two(args, input_lines): "Process part two of the puzzle" # 1. Create the computer computer = intcode.IntCode(text=input_lines[0]) # 2. Get the maximum of the amplifiers without feedback halted = computer.run(watch=args.verbose, inp=[2]) if halted != intcode.STOP_HLT: print("Computer stopped unexpectively, reason = %d" % (halted)) solution = None else: solution = computer.outputs() if len(solution) == 0: print("No output") solution = None elif len(solution) > 1: print("Unexpected multiple output %s" % (solution)) solution = None else: print("Coordinates of the distress signal = %d" % (solution[0])) if not solution: print("Unable to coordinates of the distress signal") # 3. Return result return solution is not None
def nic_thread(n): mach = intcode.IntCode(program) inpos = 0 output = [] def input_fn(): global queues nonlocal inpos # print(f'Mach {n} asking for input') if inpos < len(queues[n]): val = queues[n][inpos] inpos += 1 else: val = -1 return val def output_fn(v): global queues nonlocal output # print(f'Mach {n} producing output {v}') output += [v] if len(output) == 3: # complete packet dest = output[0] if dest == 255: print('Packet to 255:', output[1], output[2]) import sys sys.exit(0) if dest not in queues: queues[dest] = [] queues[dest] += output[1:] print(f'Mach {n} sends packet to {dest}: {output[1:]}') output = [] mach.run(input_fn, output_fn)
def part1(filename): with open(filename) as f: inputs = list(map(int, f.readline().split(','))) inputs += [0] * 2500 ic = intcode.IntCode(inputs, 0, 0) ic.process([1]) print(f"part1 >>> test mode: 1, boost keycode: {ic.outputs}")
def test_sensor_boost(self): """Test Intcode object with samples from day 9""" # 1. Takes no input and produces a copy of itself as output. mycode = intcode.IntCode(text='109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.outputs(), [109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99]) # 2. 1102,34915192,34915192,7,4,7,99,0 should output a 16-digit number. mycode = intcode.IntCode(text='1102,34915192,34915192,7,4,7,99,0') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.outputs(), [1219070632396864]) # 3. 104,1125899906842624,99 should output the large number in the middle. mycode = intcode.IntCode(text='104,1125899906842624,99') self.assertEqual(mycode.run(), intcode.STOP_HLT) self.assertEqual(mycode.outputs(), [1125899906842624])
def boost(codes): computer = intcode.IntCode(codes) outputs = run_program(computer, [2]) if outputs is None or len(outputs) > 1: print('Error: invalid output', output) return None return outputs[0]
def __init__(self, text=None): # 1. Set the initial values self.computer = intcode.IntCode(text=text) self.out = None self.inp = None self.items = None self.carrying = None self.attempting = 256
def test_1(self): input = [ 109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99 ] output_sink = TestOutputSink() computer = intcode.IntCode(TestInputProvider(0), output_sink) computer.run_to_completion(input) self.assertSequenceEqual(input, output_sink.output)
def test(codes): computer = intcode.IntCode(codes) outputs = run_program(computer, [1]) if outputs is None or len(outputs) > 1: print('Error: invalid op codes', outputs[:-1]) return None return outputs[0]
def part1(code): program = intcode.IntCode(code) blocks = 0 while not program.halted: program.run() program.run() blocktype = program.run() blocks += blocktype == 2 return blocks
def run_boost(in_val): code = day9_input() out_queue = queue.Queue() prg = intcode.IntCode(code) prg.output = lambda x: out_queue.put(x) prg.input.put(in_val) prg.run() while not out_queue.empty(): print(f'OUT: {out_queue.get()}')
def part1(filename): with open(filename) as f: codes = [int(i) for i in f.readline().split(',')] ncodes = list(codes) ncodes[1] = 12 ncodes[2] = 2 ic = intcode.IntCode(ncodes, 0, 0) ic.process([]) print(f"part1 >>> code 0@{ic.inputs[0]}")
def __init__(self, origin=(0, 0), text=None): # 1. Set the initial values self.origin = (0, 0) self.state = STATE_SEARCHING self.computer = intcode.IntCode(text=text) self.ship = ship.Ship() self.loc = origin self.next_cmd = MOVE_NORTH self.oxygen = None
def part1(filename): with open(filename) as f: inputs = list(map(int, f.readline().split(','))) perms = list(permutations(range(0, 5))) hsignal = 0 for perm in perms: ic0 = intcode.IntCode(list(inputs), 0, 0) ic0.process([perm[0], 0]) ic1 = intcode.IntCode(list(inputs), 0, 0) ic1.process([perm[1]] + ic0.outputs) ic2 = intcode.IntCode(list(inputs), 0, 0) ic2.process([perm[2]] + ic1.outputs) ic3 = intcode.IntCode(list(inputs), 0, 0) ic3.process([perm[3]] + ic2.outputs) ic4 = intcode.IntCode(list(inputs), 0, 0) ic4.process([perm[4]] + ic3.outputs) if hsignal < ic4.outputs[-1]: hsignal = ic4.outputs[-1] print(f"part1 >>> highest signal for thrusters {hsignal}")
async def _run_amps_with_feedback(self, permutation, raw_code): amp_a = intcode.IntCode(raw_code) amp_b = intcode.IntCode(raw_code, amp_a.output_queue) amp_c = intcode.IntCode(raw_code, amp_b.output_queue) amp_d = intcode.IntCode(raw_code, amp_c.output_queue) amp_e = intcode.IntCode(raw_code, amp_d.output_queue) amp_a.input_queue = amp_e.output_queue await amp_a.input_queue.put(permutation[0]) await amp_a.input_queue.put(0) await amp_b.input_queue.put(permutation[1]) await amp_c.input_queue.put(permutation[2]) await amp_d.input_queue.put(permutation[3]) await amp_e.input_queue.put(permutation[4]) output = await asyncio.gather(*(amp.run() for amp in (amp_a, amp_b, amp_c, amp_d, amp_e))) return output[-1]
async def _run_amps(self, permutation, raw_code): amp_a = intcode.IntCode(raw_code) amp_b = intcode.IntCode(raw_code, amp_a.output_queue) amp_c = intcode.IntCode(raw_code, amp_b.output_queue) amp_d = intcode.IntCode(raw_code, amp_c.output_queue) amp_e = intcode.IntCode(raw_code, amp_d.output_queue) amp_a.input_queue = asyncio.Queue() await amp_a.input_queue.put(permutation[0]) await amp_a.input_queue.put(0) await amp_b.input_queue.put(permutation[1]) await amp_c.input_queue.put(permutation[2]) await amp_d.input_queue.put(permutation[3]) await amp_e.input_queue.put(permutation[4]) await amp_a.run() await amp_b.run() await amp_c.run() await amp_d.run() return await amp_e.run()