예제 #1
0
class Robot(object):
    def __init__(self, program):
        self._intcode = IntCode(program)
        self._position = Position(0, 0)
        self._direction = Vector(0, 1)
        self._board = Board(1000, 1000)
        self._output_mode = OutputMode.COLOR
        self._paint_counter = {}

    def set_start_white(self):
        self._board.set(0, 0, Colors.WHITE.char)

    def input(self):
        char = self._board.get(self._position.x, self._position.y)
        return Colors.char2value(char)

    def output(self, value):
        if self._output_mode == OutputMode.COLOR:
            char = Colors.value2char(value)
            self._board.set(self._position.x, self._position.y, char)
            self._paint_counter[self._position] = 1
        elif self._output_mode == OutputMode.ROTATE:
            self._direction = self._direction.rotate(value)
            self._position += self._direction
        self._output_mode = OutputMode.alternate(self._output_mode)

    def run(self):
        self._intcode.execute(self.input, self.output)
        self._board.set(self._position.x, self._position.y,
                        self._direction.char())
        self._board.print()
        painted = sum(self._paint_counter.values())
        print("The robot painted {} panels".format(painted))
예제 #2
0
def solve(lines):
    board = Board(do_translate=False, fill_value=0, dtype=np.int_)
    for line in lines:
        for point in line.points():
            cur = board.get(point.x, point.y)
            board.set(point.x, point.y, cur + 1)
    return np.sum(board.grid >= 2)
예제 #3
0
class Mapper(object):
    def __init__(self, intcode):
        self._board = Board(SIZE, SIZE)
        self._nodes = Board(SIZE,
                            SIZE,
                            fill_value=Node(0, NodeType.UNKNOWN, None, 9999),
                            dtype=np.object_)
        for y in range(SIZE):
            for x in range(SIZE):
                self._nodes.grid[y][x] = Node(0, NodeType.UNKNOWN, None, 9999)
        self._x = self._y = 0
        start_node = Node(1, NodeType.START, None, 0)
        self._nodes.set(self._x, self._y, start_node)
        self._board.set(self._x, self._y,
                        self._nodes.get(self._x, self._y).type.value)
        self._current_direction = Directions.NORTH
        self._current_node = start_node
        self._intcode = intcode
        self._counter = 0
        self._goal = None

    def map(self):
        try:
            self._intcode.execute(self._input, self._output)
        except Complete:
            self._draw_solved_map()
            return self._goal, self._nodes

    def _draw_solved_map(self):
        current = self._goal
        while current.type is not NodeType.START:
            c = self._board.get(current.x, current.y)
            self._board.set(current.x, current.y, Back.GREEN + c + Back.RESET)
            current = current.parent
        self._board.print()
        print("Distance to goal: {}".format(self._goal.distance))

    def is_map_complete(self):
        if self._goal is None:
            return False
        for row in self._nodes.grid:
            if all(node.type is NodeType.UNKNOWN for node in row):
                continue
            if any(0 < node.visits < 4 for node in row):
                return False
        return True

    def _input(self):
        best = None
        for direction in Directions:
            x, y = direction.move(self._x, self._y)
            candidate = self._nodes.get(x, y)
            if best is None or candidate.visits < best[0].visits:
                best = (candidate, direction)
        self._current_direction = best[1]
        return self._current_direction

    def _output(self, v):
        if v == Status.WALL:
            x, y = self._current_direction.move(self._x, self._y)
            node = Node(9999,
                        NodeType.WALL,
                        self._current_node,
                        9999,
                        x=x,
                        y=y)
            self._nodes.set(x, y, node)
            self._board.set(x, y, node.type.value)
        else:
            self._x, self._y = self._current_direction.move(self._x, self._y)
            prev_node, node = self._current_node, self._nodes.get(
                self._x, self._y)
            self._current_node = node
            node.x = self._x
            node.y = self._y
            node.visits += 1
            if node.distance > prev_node.distance:
                node.distance = prev_node.distance + 1
                node.parent = prev_node
            if v == Status.GOAL:
                node.type = NodeType.GOAL
                self._goal = node
            elif node.type != NodeType.START:
                node.type = NodeType.OPEN
            self._board.set(self._x, self._y, node.type.value)
        self._counter += 1
        if self._counter % 5 == 0:
            prev = self._board.set(
                self._x, self._y,
                Fore.RED + self._current_direction.char + Fore.RESET)
            self._board.print()
            self._board.set(self._x, self._y, prev)
        if self.is_map_complete():
            raise Complete()