Beispiel #1
0
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"]
Beispiel #2
0
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)
Beispiel #3
0
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
Beispiel #4
0
def part1(input):
    """
    >>> import aoc_input as inp; part1(inp.read(5))
    12896948
    """
    ic = Computer(input, [1])
    ic.run()
    return ic.outputs[-1]
Beispiel #5
0
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')
Beispiel #6
0
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]
Beispiel #7
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]
Beispiel #8
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])
Beispiel #9
0
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
Beispiel #10
0
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)
Beispiel #11
0
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]
Beispiel #12
0
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)
Beispiel #13
0
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
Beispiel #14
0
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)
Beispiel #15
0
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
Beispiel #16
0
def part2(input):
    """
    >>> import aoc_input as inp; part2(inp.read(5))
    7704130
    """
    ic = Computer(input, [5])
    return ic.run()
Beispiel #17
0
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)
Beispiel #18
0
def part2(input):
    """
    >>> import aoc_input as inp; part2(inp.read(9))
    33343
    """
    ic = Computer(input, [2])
    coords = ic.run()
    return coords
Beispiel #19
0
def part1(input):
    """
    >>> import aoc_input as inp; part1(inp.read(9))
    3780860499
    """
    ic = Computer(input, [1])
    res = ic.run()
    return res
Beispiel #20
0
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
Beispiel #21
0
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
Beispiel #22
0
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
Beispiel #23
0
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]
Beispiel #24
0
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]
Beispiel #25
0
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])
Beispiel #26
0
 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,
             )
Beispiel #27
0
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
Beispiel #28
0
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())
Beispiel #29
0
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
Beispiel #30
0
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