예제 #1
0
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)
예제 #2
0
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()
예제 #3
0
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
예제 #4
0
 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
예제 #5
0
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
예제 #6
0
 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
예제 #7
0
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)
예제 #8
0
    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
        }
예제 #9
0
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)
예제 #10
0
    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
        }
예제 #11
0
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
예제 #12
0
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)
예제 #13
0
    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
        }
예제 #14
0
    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
        }
예제 #15
0
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
예제 #16
0
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
예제 #17
0
    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
        }
예제 #18
0
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
예제 #19
0
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
예제 #20
0
 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()
예제 #21
0
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
예제 #22
0
 def __init__(self, program):
     self.__cpu = Machine(program, self.__get_input, self.__get_output)
     self.__input = None
     self.__input_it = iter(())
     self.__output = []
예제 #23
0
 def __init__(self, program, springscript):
     self.__cpu = Machine(program, self.__get_input, lambda v: None)
     self.__script = springscript
     self.__it = iter(self.__script)
예제 #24
0
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()
예제 #25
0
 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
예제 #26
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)
예제 #27
0
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)
예제 #28
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)