def run_feedback_loop(phase_settings): """ Modify the computer to use Queues for inputs and outputs. Computer will block if input required and input Queue is empty. Will run each computer in a separate thread so they can run simultaneously. """ program = icc.load_data("day_7_data.txt") thread_pool = [] thread_pool_size = 5 # Setup pool of amp int code computers with feedback configuration amp_pool = [] amp_pool.append(icc.IntCodeComputer(program)) amp_pool.append(icc.IntCodeComputer(program, amp_pool[0].output)) amp_pool.append(icc.IntCodeComputer(program, amp_pool[1].output)) amp_pool.append(icc.IntCodeComputer(program, amp_pool[2].output)) amp_pool.append( icc.IntCodeComputer(program, amp_pool[3].output, amp_pool[0].input)) # Pre-load all the pahse settings for i in range(thread_pool_size): amp_pool[i].input.put(phase_settings[i]) # Give Amp 0 the starting input value of 0 amp_pool[0].input.put(0) for i in range(thread_pool_size): # Setup a worker thread for each amp and insert the phase settings # input each of the input queues. worker_thread = threading.Thread(target=amp_pool[i].run_program) # Deamonise the threads (so the die nicely when the script ends # May not be needed but stops stray threads being left behind if # we have a crash or some other weird exit. worker_thread.daemon = True # Start each of the threads running worker_thread.start() # Add them to pool list so we can keep track of them thread_pool.append(worker_thread) # Wait here for all the threads to exit properly for thd in thread_pool: thd.join() return amp_pool[4].result
def __init__(self, int_code, address): self.int_code = int_code.copy() # The intcode needs the address as the first input value. self.input_stream = self.InputStream([address]) self.output_stream = [] self.computer = int_code_computer.IntCodeComputer( self.int_code, self.input_stream, self.output_stream)
def __init__(self, int_code: List[int], mode: Mode) -> None: self._input_stream: List[int] = [] self._output_stream: List[int] = [] my_int_code = int_code.copy() my_int_code[0] = mode.value self._computer = int_code_computer.IntCodeComputer(my_int_code, self._input_stream, self._output_stream)
def part2(input_list): int_code = parse_input(input_list[0]) input_stream = [2] output_stream = [] computer = int_code_computer.IntCodeComputer(int_code, input_stream, output_stream) computer.run() return output_stream[-1]
def __init__(self, int_code): self._location = aoc.Coord(0, 0) self._input_stream = [] self._output_stream = [] self.icc = int_code_computer.IntCodeComputer(int_code, self._input_stream, self._output_stream)
def __init__(self, int_code, ship, start_color=0): self._input_stream = [start_color] self._output_stream = [] self._computer = int_code_computer.IntCodeComputer(int_code, self._input_stream, self._output_stream) self._direction = aoc.Coord(0, 1) self._location = aoc.Coord(0, 0) self._ship = ship self._paint_used = 0
def main(): """ Main Program """ print('Part 1:') program = icc.load_data('day_17_data.txt') comp = icc.IntCodeComputer(program) comp.run_program() maze_raw = [] while not comp.output.empty(): maze_raw.append(comp.output.get()) maze = build_maze(maze_raw) crossings = find_crossings(maze) print_maze(maze) print(f"\nAlignment sum = {sum_alignments(crossings)}") print('\nPart 2:') program = icc.load_data('day_17_data.txt') program[0] = 2 # Wake up the robot comp = icc.IntCodeComputer(program) # Load the movement instructions for ins in build_instructions(): comp.input.put(ins) # Load the y/n for video feed comp.input.put(ord('n')) comp.input.put(ord('\n')) comp_thread = threading.Thread(target=comp.run_program) comp_thread.daemon = True comp_thread.start() output = [] while True: out = comp.output.get() output.append(out) try: print(chr(out), end='') except ValueError: print(out) break
def check_point(self, coord): """ :param coord: aoc.Coord to check. :return: True if point is in tractor beam area. """ input_stream = [coord.x_val, coord.y_val] output_stream = [] computer = int_code_computer.IntCodeComputer(self.int_code, input_stream, output_stream) computer.run() return output_stream[0] == 1
def simulate_amplifiers(int_code, feedback_mode): # pylint: disable=too-many-locals max_output = 0 for phase_configuration in get_phases_permutations(feedback_mode): # First computer gets 0 for input. stream_into_a = [phase_configuration[0], 0] stream_into_b = [phase_configuration[1]] stream_into_c = [phase_configuration[2]] stream_into_d = [phase_configuration[3]] stream_into_e = [phase_configuration[4]] amp_a = int_code_computer.IntCodeComputer(int_code, stream_into_a, stream_into_b) amp_b = int_code_computer.IntCodeComputer(int_code, stream_into_b, stream_into_c) amp_c = int_code_computer.IntCodeComputer(int_code, stream_into_c, stream_into_d) amp_d = int_code_computer.IntCodeComputer(int_code, stream_into_d, stream_into_e) amp_e = int_code_computer.IntCodeComputer(int_code, stream_into_e, stream_into_a) if feedback_mode: until = int_code_computer.IntCodeComputer.OUTPUT else: until = int_code_computer.IntCodeComputer.HALT while not amp_e.is_halted(): amp_a.run(until=until) amp_b.run(until=until) amp_c.run(until=until) amp_d.run(until=until) amp_e.run(until=until) last_output = stream_into_a[0] if last_output > max_output: max_output = last_output return max_output
def part2(input_list): """ Run thermal radiator controller diagnostic. """ int_code = parse_input(input_list[0]) input_stream = [5] # System ID for thermal radiator controller. output_stream = [] computer = int_code_computer.IntCodeComputer(int_code, input_stream, output_stream) computer.run() return output_stream[-1]
def part1(input_list): """ Basic test of int code computer. Run air conditioning diagnostic. """ int_code = parse_input(input_list[0]) input_stream = [1] # System ID for air conditioning. output_stream = [] computer = int_code_computer.IntCodeComputer(int_code, input_stream, output_stream) computer.run() return output_stream[-1]
def part1(input_list): """ Basic test of int code computer. """ int_code = int_code_computer.IntCodeComputer.parse_input(input_list[0]) int_code[1] = 12 int_code[2] = 2 computer = int_code_computer.IntCodeComputer(int_code) computer.run() return computer.get_memory(0)
def run_permutation(program, phase_values): """ Calculate the output from the amplifier bank for the given set of phase settings """ next_input_data = 0 for i in range(0, 5): computer = icc.IntCodeComputer(program, [phase_values[i], next_input_data]) computer.run_program() next_input_data = computer.result[-1] return next_input_data
def part_1(): """ Part 1: Count bricks left at the end """ program = icc.load_data('day_13_data.txt') comp = icc.IntCodeComputer(program) comp.run_program() # Build an empty grid grid = [['' for _ in range(24)] for _ in range(37)] update_grid(comp, grid) print_grid(grid) blocks_left = sum([row.count(2) for row in grid]) print(f"Part1: Blocks left = {blocks_left}")
def run(self, ascii_code): input_stream = list(map(ord, ascii_code)) output_stream = [] computer = int_code_computer.IntCodeComputer(self._int_code, input_stream, output_stream) computer.run() if output_stream[-1] < 256: camera_output = "".join(map(chr, output_stream)) damage = None else: camera_output = None damage = output_stream[-1] return camera_output, damage
def __init__(self, int_code): self._serial_number = self._next_serial_number self._next_serial_number += 1 self._input_stream = [] self._output_stream = [] self._computer = int_code_computer.IntCodeComputer( int_code, self._input_stream, self._output_stream) self._room = '' self._rooms_visited = [] self._doors = [] self._items_here = [] self._items_carried = set() self._output = "" self._keypad_code = None self._run()
def part_2(): """ Part 2: Play the game until no blocks left. """ program = icc.load_data('day_13_data.txt') # 2 = Free play program[0] = 2 # Start a thread here to run the computer comp = icc.IntCodeComputer(program) comp_thread = threading.Thread(target=comp.run_program) comp_thread.daemon = True comp_thread.start() # Build an empty grid grid = [['' for _ in range(24)] for _ in range(37)] # Run the computer and cature the next grid iteration # Apply an input to move the paddle for the next step. update_grid(comp, grid) last_ball_x = find_ball(grid) print_grid(grid) comp.input.put(-1) while not comp.halt_status: if not comp.output.empty(): update_grid(comp, grid) print_grid(grid) ball_x = find_ball(grid) paddle_x = find_paddle(grid) moves = abs(paddle_x - ball_x) if moves != 0: for _ in range(moves): if ball_x > last_ball_x: comp.input.put(1) else: comp.input.put(-1) else: comp.input.put(0) last_ball_x = ball_x print("GAME OVER")
def paint_sign(program): """ Run the intCode computer with the given painting program Give 0 as initial input then paint, move and give next input. Next imput is the colour we have painted the square or if not painted then we return black by default. 0 = Black 1 = White """ # Dict with keys of tuples for painted squares # Values = colour of paint # {(x1,y1): c1, (x2, y2):c2 ...} initial_colour = 1 painted = {(0, 0): 1} # Start a thread here to run the computer comp = icc.IntCodeComputer(program, [initial_colour]) comp_thread = threading.Thread(target=comp.run_program) comp_thread.daemon = True comp_thread.start() # Setup initial position coords = (0, 0) heading = 0 while not comp.halt_status: # Get paint colour paint_colour = comp.output.get() turn_direction = comp.output.get() #print(f"Paint= {paint_colour}, Turn= {turn_direction}") # Paint the square (overwrites any existing paint in the square) painted[coords] = paint_colour # Execute instructed move coords, heading = turn_move(turn_direction, coords, heading) # Get input for new square inp = painted.get(coords, 0) comp.input.put(inp) return painted
def part2(input_list): """ Find int code noun and verb that produces the desired output. """ desired_output = 19690720 noun = None #for PyLint verb = None #for PyLint for noun, verb in itertools.product(range(100), range(100)): int_code = int_code_computer.IntCodeComputer.parse_input(input_list[0]) int_code[1] = noun int_code[2] = verb computer = int_code_computer.IntCodeComputer(int_code) computer.run() result = computer.get_memory(0) if result == desired_output: break return noun * 100 + verb
def build_maze(): # pylint: disable=too-many-branches """ Run the maze and print out the walls """ program = icc.load_data("day_15.txt") # Start a thread here to run the computer comp = icc.IntCodeComputer(program) comp_thread = threading.Thread(target=comp.run_program) comp_thread.daemon = True comp_thread.start() maze = {} d_posn = INITIAL_POSN direction = 1 s_found = False all_done = False # Make the first move comp.input.put(direction) while not comp.waiting: time.sleep(0.1) while not all_done: while not comp.output.empty(): out = comp.output.get() d_posn = update_maze(maze, direction, out, d_posn) # Keep left hand on the wall if out == 0: if direction == 1: direction = 4 elif direction == 2: direction = 3 elif direction == 3: direction = 1 elif direction == 4: direction = 2 elif out == 1: if direction == 1: direction = 3 elif direction == 2: direction = 4 elif direction == 3: direction = 2 elif direction == 4: direction = 1 elif out == 2: s_found = True comp.input.put(direction) if s_found is True and d_posn == INITIAL_POSN: all_done = True print_maze(maze, d_posn) #min_x = min([x[0] for x in maze]) #max_x = max([x[0] for x in maze]) #min_y = min([x[1] for x in maze]) #max_y = max([x[1] for x in maze]) #print(min_x, min_y) #print(max_x, max_y) return maze
def get_beam(x, y, prog): """ Get the beam value at the given co-ords """ input_data = [x, y] comp = icc.IntCodeComputer(prog, input_data) comp.run_program() return comp.output.get()