Exemplo n.º 1
0
class RescueDrone:
    def __init__(self, code):
        self.brain = Intcode()
        self.brain.load(code)
        self.commands = {
            "n": "north",
            "s": "south",
            "e": "east",
            "w": "west",
            "t": "take",
            "d": "drop",
            "i": "inv"
        }

    def act(self, command=""):
        if command != "":
            if command[0] in self.commands:
                command = self.commands[command[0]] + command[1:]
            for c in command:
                self.brain.add_input(ord(c))
            self.brain.add_input(ord("\n"))
        self.brain.run()
        outputs = map(chr, map(int, self.brain.get_all_outputs().split()))
        self.print_output(outputs)

    def print_output(self, outputs):
        for c in outputs:
            print(c, end="")
Exemplo n.º 2
0
class Arcade:
    def __init__(self):
        self.cpu = Intcode()
        self.screen = {}

    def load_game(self, code):
        self.cpu.load(code)

    def insert_coins(self, n):
        self.cpu.code[0] = 2

    def draw_screen(self):
        tiles = {0: "░░", 1: "██", 2: "▓▓", 3: "==", 4: "()"}
        if (-1, 0) in self.screen:
            score = self.screen[(-1, 0)]
        else:
            score = -1
        print(f"██  {score:60d}  points  ██")
        for row in range(20):
            for col in range(38):
                if (col, row) in self.screen:
                    tile = tiles[self.screen[(col, row)]]
                    print(tile, end="")
            print()

    def auto_move(self):
        for x, y in self.screen.keys():
            if self.screen[(x, y)] == 3:
                paddle = x
            if self.screen[(x, y)] == 4:
                ball = x
        if paddle < ball:
            return "d"
        elif paddle > ball:
            return "a"
        else:
            return "s"

    def run(self, automatic):
        inputs = {"": 0, "a": -1, "s": 0, "d": 1, "j": -1, "k": 0, "l": 1}
        while self.cpu.state != "halted":
            self.cpu.run()
            while len(self.cpu.outputs):
                if len(self.cpu.outputs) >= 3:
                    x = self.cpu.outputs.popleft()
                    y = self.cpu.outputs.popleft()
                    tile = self.cpu.outputs.popleft()
                    self.screen[(x, y)] = tile
                else:
                    print(
                        f"ERROR: Encountered a faulty cpu output: {list(self.cpu.outputs)}"
                    )
                    break
            if self.cpu.state != "halted":
                self.draw_screen()
                if not automatic:
                    inp = input("move: ")
                else:
                    inp = self.auto_move()
                self.cpu.add_input(inputs[inp])
Exemplo n.º 3
0
def ask_about_position(data, x, y):
    beam = Intcode()
    beam.load(data)
    beam.add_input(x)
    beam.add_input(y)
    beam.run()
    return beam.get_output()
Exemplo n.º 4
0
def run():
    data = load_data("Day09.txt")
    comp = Intcode()
    comp.load(data)
    comp.add_input(1)
    comp.run()
    print(f"The BOOST keycode is {comp.get_output()}")

    comp.load(data)
    comp.add_input(2)
    comp.run()
    print(f"The coordinate is {comp.get_output()}")
Exemplo n.º 5
0
 def __init__(self, count, code):
     self.nodes = []
     self.queues = []
     self.iddles = [0] * count
     self.nat = (0, 0)
     self.nat_timer = 0
     self.nat_history = set()
     for i in range(count):
         node = Intcode()
         node.load(code)
         node.add_input(i)
         self.nodes.append(node)
         self.queues.append(deque())
Exemplo n.º 6
0
    def test_compute_intcode(self):
        computer = Intcode([
            109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101,
            0, 99
        ])
        computer.execute()
        self.assertEqual([
            109, 1, 204, -1, 1001, 100, 1, 100, 1008, 100, 16, 101, 1006, 101,
            0, 99
        ], computer.outputs)

        computer = Intcode([1102, 34915192, 34915192, 7, 4, 7, 99, 0])
        computer.add_input(1)
        output = computer.execute()
        self.assertEqual(1219070632396864, output)

        computer = Intcode([104, 1125899906842624, 99])
        computer.add_input(1)
        output = computer.execute()
        self.assertEqual(1125899906842624, output)
Exemplo n.º 7
0
def paint_area(program, initial_color):
    area = {}
    position = (0, 0)
    direction = (0, 1)
    computer = Intcode(program)

    while True:
        color = area.get(position, initial_color)
        computer.add_input(color)
        paint = computer.run()

        if paint is None:
            break

        area[position] = paint
        turn = computer.run()
        direction = compute_direction_after_turn(direction, turn)
        position = compute_position_after_forward_move(position, direction)

    return area
Exemplo n.º 8
0
class VacuumRobot:
    def __init__(self):
        self.brain = Intcode()

    def load(self, code):
        self.brain.load(code)

    def grab_camera(self):
        self.brain.run()
        return "".join(map(chr, map(int, self.brain.get_all_outputs().split())))

    def run_path(self, order, subpaths):
        self.brain.code[0] = 2  # switch to the path following mode
        line = list(map(ord, ",".join(map(str, order)) + "\n"))
        for c in line:
            self.brain.add_input(c)
        for path in subpaths:
            line = list(map(ord, ",".join(map(str, path)) + "\n"))
            for c in line:
                self.brain.add_input(c)
        line = list(map(ord, "n\n"))
        for c in line:
            self.brain.add_input(c)
        self.brain.run()
        outputs = self.brain.get_all_outputs().split()

        return outputs[-1]
Exemplo n.º 9
0
from intcode import Intcode


def load_input():
    with open("day9/input.txt") as f:
        instructions = f.read()
    return [int(x) for x in instructions.strip().split(",")]


if __name__ == "__main__":
    program = load_input()

    computer = Intcode(program)
    computer.add_input(1)
    print(computer.execute())

    computer = Intcode(program)
    computer.add_input(2)
    print(computer.execute())
Exemplo n.º 10
0
class RepairDroid:
    def __init__(self):
        self.brain = Intcode()
        self.x = 0
        self.y = 0

    def load(self, code):
        self.brain.load(code)

    def show_map(self, corridors):
        x0, x1, y0, y1 = 0, 0, 0, 0
        for place in corridors.keys():
            if place[0] < x0:
                x0 = place[0]
            if place[0] > x1:
                x1 = place[0]
            if place[1] < y0:
                y0 = place[1]
            if place[1] > y1:
                y1 = place[1]
        for y in range(y0, y1 + 1):
            for x in range(x0, x1 + 1):
                if x == self.x and y == self.y:
                    c = "[]"
                elif (x, y) in corridors:
                    if corridors[(x, y)] == -1:
                        c = "░░"
                    elif corridors[(x, y)] == -2:
                        c = "██"
                    elif corridors[(x, y)] == -10:
                        c = "GG"
                else:
                    c = "  "
                print(c, end="")
            print()

    def explore(self, corridors):
        direction = 0
        dir_to_movement = {0: 1, 1: 4, 2: 2, 3: 3}
        dx = {0: 0, 1: 1, 2: 0, 3: -1}
        dy = {0: -1, 1: 0, 2: 1, 3: 0}
        while True:
            if self.x == 0 and self.y == 0 and len(
                    corridors) > 10:  # back at the beginning
                break
            self.brain.add_input(dir_to_movement[direction])
            self.brain.run()
            info = self.brain.get_output()
            if info == 0:  # hit a wall
                corridors[(self.x + dx[direction],
                           self.y + dy[direction])] = -2
                direction = (direction + 1) % 4
            elif info == 1:  # moved
                self.x += dx[direction]
                self.y += dy[direction]
                corridors[(self.x, self.y)] = -1
                direction = (direction + 3) % 4
            elif info == 2:  # found generator
                self.x += dx[direction]
                self.y += dy[direction]
                corridors[(self.x, self.y)] = -10
                direction = (direction + 3) % 4
        self.show_map(corridors)
Exemplo n.º 11
0
class Robot(object):
    def __init__(self, program):
        self.computer = Intcode(program)
        self.area_map = {(0, 0): (EMPTY_CELL, 0)}
        self.position = (0, 0)
        self.tank_position = None

    def explore(self, previous_moves=None):
        if previous_moves is None:
            previous_moves = []
        has_moved = False
        for direction, code in directions.items():
            new_position = (self.position[0] + direction[0],
                            self.position[1] + direction[1])
            if new_position in self.area_map:
                continue
            self.computer.add_input(code)
            output = self.computer.run()
            if output == 0:
                self.area_map[new_position] = (WALL, None)
            if output == 2:
                self.tank_position = new_position
                self.area_map[new_position] = (OXYGEN_TANK,
                                               len(previous_moves) + 1)
                has_moved = True
                self.position = new_position
                self.explore(previous_moves=previous_moves + [direction])
            if output == 1:
                self.area_map[new_position] = (EMPTY_CELL,
                                               len(previous_moves) + 1)
                has_moved = True
                self.position = new_position
                self.explore(previous_moves=previous_moves + [direction])
        if not has_moved and previous_moves:
            last_move = previous_moves.pop()
            direction = (-last_move[0], -last_move[1])
            self.computer.add_input(directions[direction])
            self.computer.run()
            self.position = (self.position[0] + direction[0],
                             self.position[1] + direction[1])
            self.explore(previous_moves)

    def compute_area_matrix(self):
        cells = self.area_map.keys()

        min_x, min_y = min(cells,
                           key=lambda x: x[0])[0], min(cells,
                                                       key=lambda x: x[1])[1]
        max_x, max_y = max(cells,
                           key=lambda x: x[0])[0], max(cells,
                                                       key=lambda x: x[1])[1]
        matrix = [[" " for _ in range(max_x - min_x + 1)]
                  for _ in range(max_y - min_y + 1)]

        for (x, y), (code, distance) in self.area_map.items():
            if code == WALL:
                matrix[y - min_y][x - min_x] = "#"
            elif code == EMPTY_CELL:
                matrix[y - min_y][x - min_x] = " "
            elif code == OXYGEN_TANK:
                matrix[y - min_y][x - min_x] = "O"
            if x == y == 0:
                matrix[y - min_y][x - min_x] = "S"
        return matrix

    def display_area(self):
        for row in self.compute_area_matrix():
            print("".join(row))

    def compute_shortest_paths(self):
        grid = self.compute_area_matrix()
        oxygen_tank_position = next((i, j) for i, row in enumerate(grid)
                                    for j, value in enumerate(row)
                                    if value == "O")

        graph = {}
        for i, row in enumerate(grid):
            for j, value in enumerate(row):
                if value != "#":
                    for (x, y) in ((-1, 0), (1, 0), (0, -1), (0, 1)):
                        if 0 <= i + x < len(grid) and 0 <= j + y < len(
                                grid[0]) and grid[i + x][j + y] != "#":
                            if (i, j) in graph:
                                graph[(i, j)].append((i + x, j + y))
                            else:
                                graph[(i, j)] = [(i + x, j + y)]

        distances = {node: math.inf for node in graph}
        previous_nodes = {node: None for node in graph}
        distances[oxygen_tank_position] = 0
        queue = {node for node in graph}

        while len(queue) > 0:
            node = min(queue, key=lambda node: distances[node])
            queue.remove(node)
            for neighbor in graph[node]:
                t = distances[node] + 1
                if t < distances[neighbor]:
                    distances[neighbor] = t
                    previous_nodes[neighbor] = node
        return distances
Exemplo n.º 12
0
class SpringDroid:
    def __init__(self, data):
        self.brain = Intcode()
        self.brain.load(data)

    def walk(self, code):
        for line in code:
            for char in line:
                self.brain.add_input(ord(char))
            self.brain.add_input(ord("\n"))
        for c in "WALK":
            self.brain.add_input(ord(c))
        self.brain.add_input(ord("\n"))

        self.brain.run()
        output = list(map(int, self.brain.get_all_outputs().split()))
        return output

    def run(self, code):
        for items in code:
            line = " ".join(items)
            for char in line:
                self.brain.add_input(ord(char))
            self.brain.add_input(ord("\n"))
        for c in "RUN":
            self.brain.add_input(ord(c))
        self.brain.add_input(ord("\n"))

        self.brain.run()
        output = list(map(int, self.brain.get_all_outputs().split()))
        return output

    def run_and_score(self, code):
        for items in code:
            line = " ".join(items)
            for char in line:
                self.brain.add_input(ord(char))
            self.brain.add_input(ord("\n"))
        for c in "RUN":
            self.brain.add_input(ord(c))
        self.brain.add_input(ord("\n"))

        self.brain.run()

        output = list(map(int, self.brain.get_all_outputs().split()))

        outcome = output[-1] if output[-1] > 255 else 0

        return self.brain.instructions_executed, outcome
Exemplo n.º 13
0
class Breakout(object):
    def __init__(self, program, mode=None):
        self.program = program
        if mode:
            self.program[0] = mode
        self.computer = Intcode(program)

    def display(self):
        array = [[" " for _ in range(max(self.computer.outputs[::3]) + 1)] +
                 [str(j).rjust(3)]
                 for j in range(max(self.computer.outputs[1::3]) + 1)]

        for (x, y, tile) in zip(self.computer.outputs[::3],
                                self.computer.outputs[1::3],
                                self.computer.outputs[2::3]):
            if (x, y) == (-1, 0):
                continue

            symbols = {0: " ", 1: "/", 2: "#", 3: "_", 4: "O"}
            array[y][x] = symbols[tile]

        for row in array:
            print("".join([x.rjust(3) for x in row]))
        print("".join([str(i).rjust(3) for i in range(len(array[0]))]))

    def get_paddle_position(self):
        paddle = self.computer.outputs[2::3][::-1].index(3)
        return self.computer.outputs[::3][::-1][paddle], self.computer.outputs[
            1::3][::-1][paddle]

    def get_ball_position(self):
        ball = self.computer.outputs[2::3][::-1].index(4)
        return self.computer.outputs[::3][::-1][ball], self.computer.outputs[
            1::3][::-1][ball]

    def compute_score(self):
        for x, y, tile in zip(self.computer.outputs[::3][::-1],
                              self.computer.outputs[1::3][::-1],
                              self.computer.outputs[2::3][::-1]):
            if (x, y) == (-1, 0):
                return tile
        return 0

    def count_blocks(self):
        return self.computer.outputs[2::3].count(2)

    def play(self):
        breakout.computer.execute()
        while not self.computer.stopped:
            paddle_position = self.get_paddle_position()
            ball_position = self.get_ball_position()

            if paddle_position[0] > ball_position[0]:
                instruction = -1
            elif paddle_position[0] < ball_position[0]:
                instruction = 1
            else:
                instruction = 0

            self.computer.add_input(instruction)
            self.computer.execute()
Exemplo n.º 14
0
def is_affected_by_beam(i, j, program):
    computer = Intcode(program)
    computer.add_input(i)
    computer.add_input(j)
    computer.execute()
    return computer.outputs[0] == 1