Beispiel #1
0
    def find_closest_square_under_beam(self, expected_width, expected_high):
        for y in range(750, 1500):
            for x in range(1500, 2000):
                computer = IntcodeComputer()
                computer.feed(x)
                computer.feed(y)
                # print(f'feed ({x}, {y})')
                value = next(computer)
                if not value:
                    continue

                computer = IntcodeComputer()
                computer.feed(x + 99)
                computer.feed(y)
                value = next(computer)
                if not value:
                    continue

                computer = IntcodeComputer()
                computer.feed(x)
                computer.feed(y + 99)
                value = next(computer)
                if not value:
                    continue

                return _get_part2_result(x, y)

        raise RuntimeError()
Beispiel #2
0
    def __init__(self, inp=None, mode=None):
        # key (tuple) : coordinates
        self.map = collections.defaultdict(
            tuple  # value: current_color (int), painted (bool)
        )

        self.computer = IntcodeComputer(inp, mode)

        self.direction = 0  # up
Beispiel #3
0
    def count_ones(self, max_x, max_y):
        _map = collections.defaultdict(int)
        for y in range(max_y):
            for x in range(max_x):
                computer = IntcodeComputer()
                computer.feed(x)
                computer.feed(y)
                # print(f'feed ({x}, {y})')
                res = next(computer)
                # print(f'received {res}')
                _map[(x, y)] = res

        return sum(val for val in _map.values() if val)
Beispiel #4
0
    def _bfs(self, root, computer=None, mode=1):
        state = 1
        computer = computer or IntcodeComputer()
        seen = {root: (state, computer)}
        queue = collections.deque([(root, 0, computer)])
        visit_order = []
        levels = []

        while queue:
            vertex, level, parent_computer = queue.popleft()
            visit_order.append(vertex)
            levels.append(level)

            if vertex in seen:
                _node = seen[vertex]
                _state = _node[0]
                if mode == 1 and _state == 2:
                    if self.to_draw:
                        # print(visit_order)
                        # print(levels)
                        ys = [pos[1] for pos in seen.keys()]
                        xs = [pos[0] for pos in seen.keys()]
                        min_y, max_y = min(ys), max(ys)
                        min_x, max_x = min(xs), max(xs)
                        print(
                            f'after: node {node} state {state} pos {computer.pos} base {computer.relative_base}'
                        )
                        # print(f'after: vertex {vertex} pos {parent_computer.pos} base {parent_computer.relative_base}')
                        print('y from {} to {}'.format(min_y, max_y))
                        print('x from {} to {}'.format(min_x, max_x))
                        for _y in reversed(range(min_y, max_y + 1)):
                            line = []
                            for _x in range(min_x, max_x + 1):
                                if (_x, _y) == (0, 0):
                                    _draw = '*'
                                if (_x, _y) == node:
                                    _draw = 'Ж'
                                else:
                                    _node = seen.get((_x, _y), (-1, ))
                                    _state = _node[0]
                                    _draw = TILE2DRAW[_state]
                                line.append(_draw)
                            print(''.join(line))
                        # end draw region
                    return vertex, level, parent_computer

            # for node in graph.get(vertex, [0, 1, 2, 3]):
            # Only four movement commands are understood: north (1), south (2), west (3), and east (4)
            # if to_draw:
            #     print(f'before: vertex {vertex} pos {parent_computer.pos} base {parent_computer.relative_base}')
            for direction in range(1, 5):
                node = self._get_node(vertex, direction)
                if node in seen:
                    continue

                computer = parent_computer.copy()

                computer.feed(direction)
                try:
                    state = next(computer)
                    # 0: The repair droid hit a wall. Its position has not changed.
                    # 1: The repair droid has moved one step in the requested direction.
                    # 2: The repair droid has moved one step in the requested direction; its new position is the location of the oxygen system.
                except StopIteration as e:
                    break

                # print('compare {node} to {vertex}:')
                # for i, val in enumerate(computer.memory):
                #     if val != seen[vertex][-1].memory[i]:
                #         print(i, val)
                # print('compare signals:')
                # print(computer.signals)
                # print(seen[vertex][-1].signals)

                if state == 0:
                    # 0: The repair droid hit a wall. Its position has not changed.
                    pass
                else:
                    queue.append((node, level + 1, computer))

                seen[node] = (state, computer)

                # draw region
                # if to_draw:
                #     ys = [pos[1] for pos in seen.keys()]
                #     xs = [pos[0] for pos in seen.keys()]
                #     min_y, max_y = min(ys), max(ys)
                #     min_x, max_x = min(xs), max(xs)
                #     print(f'after: node {node} state {state} pos {computer.pos} base {computer.relative_base}')
                #     # print(f'after: vertex {vertex} pos {parent_computer.pos} base {parent_computer.relative_base}')
                #     print('y from {} to {}'.format(min_y, max_y))
                #     print('x from {} to {}'.format(min_x, max_x))
                #     for _y in reversed(range(min_y, max_y + 1)):
                #         line = []
                #         for _x in range(min_x, max_x + 1):
                #             if (_x, _y) == (0, 0):
                #                 _draw = '*'
                #             if (_x, _y) == node:
                #                 _draw = 'Ж'
                #             else:
                #                 _node = seen.get((_x, _y), (-1,))
                #                 _state = _node[0]
                #                 _draw = TILE2DRAW[_state]
                #             line.append(_draw)
                #         print(''.join(line))
                #     # end draw region

        if mode == 1:
            raise RuntimeError('couldnt find oxygen')
        elif mode == 2:
            return max(levels)
        raise RuntimeError(f'unknown mode {mode}')
Beispiel #5
0
def part1(*args, **kwargs):
    return IntcodeComputer(*args, signals=[1], **kwargs).compute()