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 __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
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
def __init__(self, program): self.__droid = Machine(program, self.__get_direction, self.__get_status) self.__droid.break_on_output = True self.__position = (0, 0) self.__direction = Direction.EAST self.__room_map = {(0, 0): Room.FREE} self.__decision_picker = iter(Controller.__turns) self.__area_mapped = False self.__oxygen_position = None
class Controller: __turns = [1, -1, -1, -1] def __init__(self, program): self.__droid = Machine(program, self.__get_direction, self.__get_status) self.__droid.break_on_output = True self.__position = (0, 0) self.__direction = Direction.EAST self.__room_map = {(0, 0): Room.FREE} self.__decision_picker = iter(Controller.__turns) self.__area_mapped = False self.__oxygen_position = None @property def position(self): return self.__position @property def oxygen_position(self): return self.__oxygen_position @property def room_map(self): return self.__room_map def run(self): while not self.__area_mapped: self.__droid.start_or_resume() def __get_direction(self): return self.__direction.instruction def __get_status(self, status): room = Room(status) x, y = self.__position az_x, az_y = self.__direction.azimuth new_pos = x + az_x, y + az_y self.__room_map[new_pos] = room if room is not Room.WALL: self.__position = new_pos self.__decision_picker = iter(Controller.__turns) if room is Room.OXYGEN: self.__oxygen_position = new_pos if new_pos == (0, 0): self.__area_mapped = True decision = next(self.__decision_picker) self.__direction = self.__direction.turn(decision)
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 }
class Computer: def __init__(self, id, program, send_callback): self.__id = id self.__cpu = Machine( program, self.__receive_message, self.__send__message) self.__msg_queue = deque() self.__send_callback = send_callback self.__state = SendState.NOTHING_READ self.__booted = False self.__next_dest = None self.__next_x = None self.__state_map = { SendState.NOTHING_READ: self.__store_dest, SendState.DESTINATION_READ: self.__store_x, SendState.X_READ: self.__do_send } @property def halted(self): return self.__cpu.halted def step(self): self.__cpu.step() def queue_message(self, x, y): msg = x, y self.__msg_queue.extend(msg) def __send__message(self, value): self.__state_map[self.__state](value) self.__state = self.__state.advance() def __receive_message(self): if not self.__booted: self.__booted = True return self.__id if not self.__msg_queue: return -1 next_value = self.__msg_queue.popleft() return next_value def __store_dest(self, value): self.__next_dest = value def __store_x(self, value): self.__next_x = value def __do_send(self, value): self.__send_callback(self.__next_dest, self.__next_x, value)
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 }
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)
def __init__(self, id, program, send_callback): self.__id = id self.__cpu = Machine( program, self.__receive_message, self.__send__message) self.__msg_queue = deque() self.__send_callback = send_callback self.__state = SendState.NOTHING_READ self.__booted = False self.__next_dest = None self.__next_x = None self.__state_map = { SendState.NOTHING_READ: self.__store_dest, SendState.DESTINATION_READ: self.__store_x, SendState.X_READ: self.__do_send }
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 }
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
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 }
def run_feedback_loop(phases, prog): links = [Link(p, 0) for p in phases] linkage = pairwise(cycle(links)) comps = [ Machine(deepcopy(prog), i, o) for i, o in islice(linkage, len(links)) ] for c in comps: c.break_on_output = True while not all(c.halted for c in comps): for c in comps: c.start_or_resume() return comps[-1].last_output
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(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()
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
def __init__(self, program): self.__cpu = Machine(program, self.__get_input, self.__get_output) self.__input = None self.__input_it = iter(()) self.__output = []
def __init__(self, program, springscript): self.__cpu = Machine(program, self.__get_input, lambda v: None) self.__script = springscript self.__it = iter(self.__script)
from utils.parse import Parser from aoc.intcode import Machine from copy import deepcopy parser = Parser("Day 9: Sensor Boost - Part 2") parser.parse() with parser.input as input: line = input.readline() program = [int(el) for el in line.split(',')] program_input = lambda: 2 computer = Machine(deepcopy(program), program_input) computer.run()
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
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)
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 from copy import deepcopy parser = Parser("Day 2: 1202 Program Alarm - Part 1") parser.parse() with parser.input as input: line = input.readline() program = [int(el) for el in line.split(',')] program[1] = 12 program[2] = 2 computer = Machine(deepcopy(program), lambda: None) computer.run() zero_pos = computer.read(0) print(zero_pos)