def part2(pc: intcode.Computer) -> int: pc.reset(wait_for_input=True) pc.data[0] = 2 # initial setup pc.run() idx = pc.output.index(-1) while pc.output[idx + 1] != 0: idx = pc.output.index(-1, idx + 1) entities = getEntities(pc.output[:idx]) pc.output = pc.output[idx:] # loop while not pc.stop: pc.run() changes = getEntities(pc.output) if changes["score"]: entities["score"] = changes["score"] if changes["ball"]: changes["empty"].remove(entities["ball"]) entities["ball"] = changes["ball"] if changes["paddle"]: changes["empty"].remove(entities["paddle"]) entities["paddle"] = changes["paddle"] for e in changes["empty"]: entities["block"].remove(e) pc.output.clear() pc.input = entities["ball"][0] - entities["paddle"][0] return entities["score"]
def _part2(program, target): computer = Computer(program) noun = _search_noun(computer, 0, 100, target) verb = _search_verb(computer, noun, 0, 100, target) computer.run(noun, verb) assert computer.memory[0] == target print("Part 2:", noun * 100 + verb)
def part2(pc: intcode.Computer) -> int: for noun in range(100): for verb in range(100): pc.reset() pc.data[1], pc.data[2] = noun, verb pc.run() if pc.data[0] == 19690720: return 100 * noun + verb
def part1(input): """ >>> import aoc_input as inp; part1(inp.read(5)) 12896948 """ ic = Computer(input, [1]) ic.run() return ic.outputs[-1]
class Robot(): def __init__(self, program): # direction 0 = up, 1 = left, 2 = down, 3 = right self.coords = np.zeros(2, dtype=np.int32) self.direction = 0 self.hull = dict() self.input_list = [] self.computer = Computer(program, self.input_list) def run(self): # detect color of curent panel, run program, paint, turn, and step # rinse and repeat while not self.computer.done: color = self.hull.get(tuple(self.coords), 0) self.input_list.insert(0, color) if len(self.input_list) != 1: logging.warning("Input list length: %d", len(self.input_list)) new_color = self.computer.run() if self.computer.done: break self.hull[tuple(self.coords)] = new_color turn_instruction = self.computer.run() if self.computer.done: break self.turn(turn_instruction) self.step() def turn(self, val): if val == 0: # turn left self.direction = (self.direction + 1) % 4 elif val == 1: # turn right self.direction = (self.direction - 1) % 4 else: raise ValueError("Turn value is {}.".format(val)) def step(self): if self.direction == 0: self.coords[1] += 1 elif self.direction == 1: self.coords[0] -= 1 elif self.direction == 2: self.coords[1] -= 1 elif self.direction == 3: self.coords[0] += 1 else: raise RuntimeError("Bad direction {}.".format(self.direction)) def show_hull(self): coords = np.array(list(self.hull.keys())) min_coords = np.min(coords, axis=0) coords -= min_coords max_coords = np.max(coords, axis=0) img = np.zeros(max_coords + 1, dtype=np.int32) for coord, color in self.hull.items(): new_coord = np.array(coord) - min_coords img[new_coord[0], new_coord[1]] = color plt.imshow(img.T, origin='lower') plt.savefig('problem11b.jpg')
class CheckPoint: def __init__(self, source): self.prog = [int(c) for c in source.split(',')] self.comp = Computer(self.prog) def __call__(self, inp): self.comp.reset(self.prog) self.comp.run(inp) return self.comp.output[0]
def part1(input): """ >>> import aoc_input as inp; part1(inp.read(2)) 4138687 """ ic = Computer(input) ic.seq[1] = 12 ic.seq[2] = 2 ic.run() return ic.seq[0]
def _main(): with open(asset("day5.txt")) as file: memory = [int(value) for value in file.read().split(',')] computer = Computer(memory, verbose=True) print("Part 1:") computer.run(inputs=[1]) print("Part 2:") computer.run(inputs=[5])
def find_max_thrust(code): max_thrust = 0 for phases in itertools.permutations(range(5), 5): val = 0 for phase in phases: c = Computer(code) c.run([phase, val]) val = c.output[0] if c.output[0] > max_thrust: max_thrust = c.output[0] best = phases return best, max_thrust
class Game: def __init__(self, code: List[int]): self.grid: DefaultDict[Index, Tile] = defaultdict(lambda: Tile.EMPTY) self.computer = Computer(code=code) self.score = 0 self.ball_pos = (0, 0) self.paddle_pos = (0, 0) def draw(self, move: int = 0) -> None: self.computer.inputs.append(move) try: while True: pixel = self.get_pixel() if pixel: self.grid[pixel.pos] = pixel.tile if pixel.tile == Tile.BALL: self.ball_pos = pixel.pos if pixel.tile == Tile.PADDLE: self.paddle_pos = pixel.pos except (IntcodeTerminated, InputRequested): return def get_pixel(self) -> Optional[Pixel]: x = self.computer.run() y = self.computer.run() result = self.computer.run() if (x, y) == (-1, 0): self.score = result pixel = None else: pixel = Pixel((x, y), Tile(result)) return pixel def min_x(self) -> int: return min(i_x for i_x, _ in self.grid.keys()) def max_x(self) -> int: return max(i_x for i_x, _ in self.grid.keys()) def min_y(self) -> int: return min(i_y for _, i_y in self.grid.keys()) def max_y(self) -> int: return max(i_y for _, i_y in self.grid.keys()) def __str__(self) -> str: pixels: List[str] = [f"Score = {self.score}\n"] for j in range(self.min_y(), self.max_y()): for i in range(self.min_x(), self.max_x() + 1): pixels.append(TILE_CHARACTERS[self.grid[(i, j)]]) pixels.append('\n') return ''.join(pixels)
def amplification(phase_setting, opcodes): vals = [0] for setting in phase_setting: def inp(): yield setting yield vals[-1] def out(x): vals.append(x) gen = inp() cpu = Computer(opcodes.copy(), inp=lambda: next(gen), out=out) cpu.run() return vals[-1]
def _part1(program, verbose=False): max_value = 0 for settings in itertools.permutations([0, 1, 2, 3, 4]): value = 0 for setting in settings: computer = Computer(program) computer.run(inputs=[setting, value]) value = computer.read() if value > max_value: if verbose: print("new max:", settings, value) max_value = value print("Part 1:", max_value)
class Drone(): def __init__(self, program, map_size): self._program = program self.input_list = [] # initialize map values to -1 to indicate unexplored self.map = -1 * np.ones((map_size, map_size), dtype=np.int8) def update_position(self, x, y): self.input_list += [y, x] # didn't think I'd need to reset the program every time, but it didn't # work otherwise self.computer = Computer(np.copy(self._program), self.input_list) output = self.computer.run() self.map[y, x] = output return output def get_map(self): display_chars = np.array(['.', '#', '?']) char_array = display_chars[self.map] lines = [''.join(list(row)) for row in char_array] return '\n'.join(lines) def get_min_and_max(self, row_id): x_vals = np.where(self.map[row_id] == 1)[0] if x_vals.size == 0: return 0, 0 min_x = np.min(x_vals) max_x = np.max(x_vals) return min_x, max_x
def get_ship_map(): robot = Computer(read("inputs/day_15.txt")) pos = (0, 0) ship_map = {} moves = [] # contains directions (value) we haven't attempted for each # coordinate (key) unexplored = {} while True: if pos not in unexplored: unexplored[pos] = [1, 2, 3, 4] if unexplored[pos]: back_tracking = False move = unexplored[pos].pop() else: back_tracking = True if not moves: # backtracked to start return ship_map prev = moves.pop() move = get_opposite(prev) robot.add_input(move) status = robot.run() if status in (SUCCESSFUL_MOVE, OXYGEN): pos = make_move(pos, move) ship_map[pos] = status if not back_tracking: moves.append(move)
def problem17a(camera_output=None): if camera_output is None: file_name = 'day17/problem17.txt' program = np.loadtxt(file_name, np.int32, delimiter=',') computer = Computer(program) camera_output = '' while not computer.done: output = computer.run() if output is not None: camera_output += chr(output) print(camera_output) lines = camera_output.split('\n') char_array = np.array([list(line) for line in lines if line]) intersections = [] n_rows, n_cols = char_array.shape for irow in range(n_rows): for icol in range(n_cols): if char_array[irow, icol] == '#': cross_row = ((irow > 0) and (char_array[irow-1, icol] == '#')) \ and ((irow < n_rows-1) and (char_array[irow+1, icol] == '#')) cross_col = ((icol > 0) and (char_array[irow, icol-1] == '#')) \ and ((icol < n_cols-1) and (char_array[irow, icol+1] == '#')) if cross_row and cross_col: coords = (irow, icol) intersections.append(coords) intersection_array = np.array(intersections) alignment = np.sum(np.prod(intersection_array, axis=1)) return alignment
def part2(input): """ >>> import aoc_input as inp; part2(inp.read(5)) 7704130 """ ic = Computer(input, [5]) return ic.run()
class Robot: def __init__(self, code: List[int]): self.grid: DefaultDict[Index, int] = defaultdict(int) self.computer = Computer(code=code) self.pos = (0, 0) self.dir = (0, 1) self.grid[(0, 0)] = 1 def turn(self, turn_code: int) -> None: if turn_code == 0: self.dir = (-self.dir[1], self.dir[0]) elif turn_code == 1: self.dir = (self.dir[1], -self.dir[0]) def run(self) -> int: visited: Set[Index] = {self.pos} try: while True: paint_output = self.computer.run(self.grid[self.pos]) self.grid[self.pos] = paint_output turn_output = self.computer.run(self.grid[self.pos]) self.turn(turn_output) self.pos = (self.pos[0] + self.dir[0], self.pos[1] + self.dir[1]) visited.add(self.pos) except IntcodeTerminated: return len(visited) def min_x(self) -> int: return min(i_x for i_x, _ in self.grid.keys()) def max_x(self) -> int: return max(i_x for i_x, _ in self.grid.keys()) def min_y(self) -> int: return min(i_y for _, i_y in self.grid.keys()) def max_y(self) -> int: return max(i_y for _, i_y in self.grid.keys()) def __str__(self) -> str: pixels = [] for j in range(self.max_y(), self.min_y() - 1, -1): for i in range(self.min_x(), self.max_x() + 1): pixels.append('#' if self.grid[(i, j)] else '.') pixels.append('\n') return ''.join(pixels)
def part2(input): """ >>> import aoc_input as inp; part2(inp.read(9)) 33343 """ ic = Computer(input, [2]) coords = ic.run() return coords
def part1(input): """ >>> import aoc_input as inp; part1(inp.read(9)) 3780860499 """ ic = Computer(input, [1]) res = ic.run() return res
def problem5a(): file_name = 'day05/problem5.txt' program = np.loadtxt(file_name, np.int32, delimiter=',') computer = Computer(program, [1]) output = 0 while not output: output = computer.run() return output
def part2(input): """ >>> import aoc_input as inp; part2(inp.read(2)) 6635 """ ic = Computer(input) target_val = 19690720 for noun in range(99): for verb in range(99): ic.reset() ic.seq[1] = noun ic.seq[2] = verb ic.run() if ic.seq[0] == target_val: break if ic.seq[0] == target_val: break return 100 * noun + verb
def paint(codes, start=0): c = Computer(codes) loc = Point(0, 0) direc = Vector(0, 1, 0) panels = {loc: start} while c.running: c.run([panels.get(loc, 0)]) turn = c.output.pop() color = c.output.pop() panels[loc] = color if turn == 0: # Turn left direc = Vector.k().cross(direc) elif turn == 1: # Turn right direc = direc.cross(Vector.k()) loc += direc return panels
def part_one(): c = Computer(read("inputs/day_05.txt"), inputs=[1]) outputs = [] while not c.finished: output = c.run() if output is not None: outputs.append(output) return outputs[-1]
def test_problem9a(): test_program = [ 109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101, 0, 99 ] computer = Computer(np.copy(test_program), []) outputs = [] while not computer.done: outputs.append(computer.run()) assert outputs[:-1] == test_program test_program = [1102, 34915192, 34915192, 7, 4, 7, 99, 0] computer = Computer(np.copy(test_program), []) output = computer.run() int_str = str(output) assert len(int_str) == 16 test_program = [104, 1125899906842624, 99] computer = Computer(np.copy(test_program), []) output = computer.run() assert output == test_program[1]
def get_painted_panels(starting_panel): painter = Computer(read("inputs/day_11.txt")) painter.add_input(starting_panel) panels = defaultdict(int) direction = 0 position = (0, 0) outputs = [] while (output := painter.run()) is not None: outputs.append(output) if len(outputs) == 2: turn = outputs.pop() colour = outputs.pop() panels[position] = colour direction = make_turn(direction, turn) position = make_move(position, direction) painter.add_input(panels[position])
def get_children(self) -> Iterator[Node]: for command in MOVE_COMMANDS: output: List[int] = [] child_computer = Computer(code=self.computer.code, output=output) child_computer.inputs.append(command) try: child_computer.run() except InputRequested: pass if output[-1] == 2: yield Node( computer=child_computer, location=self.location + MOVE_VECTORS[command], parent=self, goal=True, ) elif output[-1] == 1: yield Node( computer=child_computer, location=self.location + MOVE_VECTORS[command], parent=self, goal=False, )
def check_sequence(program): perms = permutations(range(5)) best_perm = None max_output = 0 for sequence in perms: input_val = 0 for phase in sequence: computer = Computer(np.copy(program), [input_val, phase]) output = computer.run() input_val = output if output > max_output: best_perm = sequence max_output = output return max_output, best_perm
def part_one(): computer = Computer(read("inputs/day_13.txt")) game = Game() outputs = [] while not computer.finished: outputs.append(computer.run()) if len(outputs) == 3: tile = outputs.pop() row = outputs.pop() col = outputs.pop() game.update(row, col, tile) return sum(c == 2 for c in game.display.values())
def main(): with open('day-09.txt', 'r') as file: data = file.read() program = [int(x) for x in data.split(',')] # program = [109,1,204,-1,1001,100,1,100,1008,100,16,101,1006,101,0,99] # program = [1102,34915192,34915192,7,4,7,99,0] # program = [104,1125899906842624,99] c = Computer(program, [1]) output = c.run() while output is not None: print(output) output = c.run() c = Computer(program, [2]) output = c.run() while output is not None: print(output) output = c.run() return
def problem13b(): file_name = 'day13/problem13.txt' program = np.loadtxt(file_name, np.int32, delimiter=',') program[0] = 2 # play for free? img_size = (37, 23) plt.ion() fig = plt.figure() joystick = 0 # start in neutral input_list = [joystick] computer = Computer(program, input_list) img = make_image(computer, img_size) mpl_img = plt.imshow(img.T) plt.axis('off') fig.canvas.draw() output_list = 3 * [None] ball_prev = np.concatenate(np.where(img == BALL)) while not computer.done: for ind in range(3): output_list[ind] = computer.run() if computer.done: break if np.all(np.array(output_list[:2]) == np.array([-1, 0])): score = output_list[2] print("Score:", score) continue img[output_list[0], output_list[1]] = output_list[2] if output_list[2] == BALL: mpl_img.set_data(img.T) fig.canvas.draw() time.sleep(0.02) ball_curr = np.array(output_list[:2]) velocity = ball_curr - ball_prev paddle_curr = np.concatenate(np.where(img == PADDLE)) if velocity[1] == 1: # ball is falling delta = paddle_curr - ball_curr ball_x_dest = ball_curr[0] + delta[1] * velocity[0] joystick = ball_x_dest - paddle_curr[0] - velocity[0] else: joystick = ball_curr[0] + velocity[0] - paddle_curr[0] joystick = max(min(joystick, 1), -1) input_list.append(joystick) ball_prev = ball_curr