class Arcade: def __init__(self, program): self.__cpu = Machine(program, lambda: None, self.__get_instructions) self.__grid = {} self.__paint_state = PaintState.NOTHING_READ self.__x = None self.__y = None self.__state_actions = { PaintState.NOTHING_READ: self.__read_x, PaintState.X_READ: self.__read_y, PaintState.Y_READ: self.__paint_tile } @property def grid(self): return self.__grid def run(self): self.__cpu.run() def __get_instructions(self, value): self.__state_actions[self.__paint_state](value) self.__paint_state = self.__paint_state.advance() def __read_x(self, x): self.__x = x def __read_y(self, y): self.__y = y def __paint_tile(self, value): coords = self.__x, self.__y self.__grid[coords] = Tile(value)
class Droid: def __init__(self, program): self.__cpu = Machine(program, self.__get_input, self.__get_output) self.__input = None self.__input_it = iter(()) self.__output = [] def run(self): self.__cpu.run() if self.__output: self.__flush_output() def __get_input(self): if self.__output: self.__flush_output() c = next(self.__input_it, None) if c is None: input_line = input('#> ') self.__input = [input_line, '\n'] self.__input_it = chain.from_iterable(self.__input) c = next(self.__input_it) return ord(c) def __get_output(self, ascii): c = chr(ascii) self.__output.append(c) def __flush_output(self): outprint = "".join(self.__output) print(outprint) self.__output.clear()
class Camera: def __init__(self, program): self.__cpu = Machine(program, lambda: None, self.__get_pixel) self.__image = {} self.__position = (0, 0) self.__char_mapping = { '.': Pixel.SPACE, '#': Pixel.SCAFFOLD, '^': Pixel.SCAFFOLD, '>': Pixel.SCAFFOLD, 'v': Pixel.SCAFFOLD, '<': Pixel.SCAFFOLD } @property def image(self): return self.__image def run(self): self.__cpu.run() def __get_pixel(self, ascii): c = chr(ascii) x, y = self.__position mapping = self.__char_mapping.get(c, None) if mapping is None: self.__position = 0, y + 1 return self.__image[self.__position] = mapping self.__position = x + 1, y
def run_series(phases, prog): value = 0 program_output = lambda v: None for p in phases: program_input = Input(p, value) computer = Machine(deepcopy(prog), program_input, program_output) computer.run() value = computer.last_output return value
class Camera: def __init__(self, program): self.__cpu = Machine(program, lambda: None, self.__get_pixel) self.__image = {} self.__position = (0, 0) self.__vacuum_robot = None self.__char_mapping = { '.': Pixel.SPACE, '#': Pixel.SCAFFOLD, '^': Pixel.ROBOT_NORTH, '>': Pixel.ROBOT_EAST, 'v': Pixel.ROBOT_SOUTH, '<': Pixel.ROBOT_WEST } self.__dir_mapping = { Pixel.ROBOT_NORTH: Direction.NORTH, Pixel.ROBOT_EAST: Direction.EAST, Pixel.ROBOT_SOUTH: Direction.SOUTH, Pixel.ROBOT_WEST: Direction.WEST } @property def image(self): return self.__image @property def vacuum_robot(self): return self.__vacuum_robot def run(self): self.__cpu.run() def __get_pixel(self, ascii): c = chr(ascii) x, y = self.__position mapping = self.__char_mapping.get(c, None) if mapping is None: self.__position = 0, y + 1 return if mapping.is_robot: self.__vacuum_robot = self.__position, self.__dir_mapping[mapping] self.__image[self.__position] = mapping self.__position = x + 1, y
class SpringDroid: def __init__(self, program, springscript): self.__cpu = Machine(program, self.__get_input, lambda v: None) self.__script = springscript self.__it = iter(self.__script) @property def output(self): return self.__cpu.last_output def run(self): self.__cpu.run() def __get_input(self): c = next(self.__it) return ord(c)
class VacuumRobot: def __init__(self, program, routine): self.__cpu = Machine(program, self.__get_routine, self.__get_dust) self.__routine = routine self.__it = iter(self.__routine) self.__dust_amount = None @property def dust_amount(self): return self.__dust_amount def run(self): self.__cpu.run() def __get_routine(self): c = next(self.__it) return ord(c) def __get_dust(self, value): self.__dust_amount = value
class Painter: def __init__(self, program): self.__cpu = Machine(program, self.__get_panel_color, self.__get_instructions) self.__coordinates = 0, 0 self.__dir = Direction.NORTH self.__grid = defaultdict(int) self.__current_color = 0 self.__color__given = False self.__painted_coordinates = set() @property def painted_coordinates(self): return self.__painted_coordinates def paint(self): self.__cpu.run() def __move(self): x_s, y_s = self.__dir.azimuth x, y = self.__coordinates self.__coordinates = x + x_s, y + y_s def __paint_panel(self): self.__grid[self.__coordinates] = self.__current_color if self.__current_color == 1: self.__painted_coordinates.add(self.__coordinates) def __get_panel_color(self): return self.__grid[self.__coordinates] def __get_instructions(self, value): if self.__color__given: turn_side = 1 if value else -1 self.__dir = self.__dir.turn(turn_side) self.__move() self.__color__given = False else: self.__current_color = value self.__paint_panel() self.__color__given = True
class Scanner: def __init__(self, program, grid_size): self.__program_copy = program self.__grid_size = grid_size self.__drone = None self.__pulled = 0 self.__next_position = None @property def pulled(self): return self.__pulled def run(self): for pos in product(range(self.__grid_size), range(self.__grid_size)): self.__next_position = iter(pos) self.__drone = Machine(deepcopy(self.__program_copy), self.__get_position, self.__get_output) self.__drone.run() def __get_position(self): return next(self.__next_position) def __get_output(self, value): self.__pulled += value
def run_with_params(program, noun, verb): program[1] = noun program[2] = verb computer = Machine(deepcopy(program), lambda: None) computer.run() return computer.read(0)
from utils.parse import Parser from aoc.intcode import Machine parser = Parser("Day 5: Sunny with a Chance of Asteroids - Part 2") parser.parse() with parser.input as input: line = input.readline() program = [int(el) for el in line.split(',')] program_input = lambda: 5 program_output = lambda v: None computer = Machine(program, program_input, program_output) computer.run() print(computer.last_output)
class Arcade: def __init__(self, program): self.__cpu = Machine(program, self.__get_joystick, self.__get_instructions) self.__grid = {} self.__paint_state = PaintState.NOTHING_READ self.__score = 0 self.__x = None self.__y = None self.__ball_current_position = None self.__pad_position = None self.__state_actions = { PaintState.NOTHING_READ: self.__read_x, PaintState.X_READ: self.__read_y, PaintState.Y_READ: self.__paint_tile } @property def grid(self): return self.__grid @property def score(self): return self.__score def run(self): self.__cpu.run() def __get_joystick(self): if self.__pad_position < self.__ball_current_position: return 1 if self.__pad_position > self.__ball_current_position: return -1 return 0 def __get_instructions(self, value): self.__state_actions[self.__paint_state](value) self.__paint_state = self.__paint_state.advance() def __read_x(self, x): self.__x = x def __read_y(self, y): self.__y = y def __paint_tile(self, value): coords = self.__x, self.__y if coords == (-1, 0): self.__score = value return tile = Tile(value) self.__grid[coords] = tile if tile is Tile.BALL: self.__ball_current_position = self.__x elif tile is Tile.PADDLE: self.__pad_position = self.__x