예제 #1
0
def part_two(grid: Grid) -> int:
    low_points = [p for p, v in grid.search(mindepth)]
    sizes = []
    for lp in low_points:
        matches = list(grid.collect_recursive([lp], notnine))
        sizes.append(len(matches))
    top3 = sorted(sizes, reverse=True)[:3]
    return math.prod(top3)
def get_seat_for_direction(grid: Grid, point: Point,
                           direction: Point) -> Optional[str]:
    next_stop = add_points(point, direction)
    next_point = grid.get(next_stop, None)
    while True:
        if next_point is None or is_seat(next_point):
            return next_point
        next_stop = add_points(next_stop, direction)
        next_point = grid.get(next_stop, None)
예제 #3
0
    def strip_border(self) -> 'Tile':
        new_points = Grid()
        for point, value in self.grid.items():
            if not self.is_edge_point(point):
                new_points[(point[0] - 1, point[1] - 1)] = value

        return Tile(self.id, new_points, self.matched_edges)
예제 #4
0
    def transform(self, point_transformer: Callable[[Point], Point]) -> 'Tile':
        new_points = Grid()
        for point, value in self.grid.items():
            new_point: Point = point_transformer(point)
            new_points[new_point] = value

        return Tile(self.id, new_points, self.matched_edges)
예제 #5
0
def both_parts(grid: Grid) -> tuple[int, int]:
    flashes = 0
    a1 = 0
    queue: Deque[Point] = deque([])

    def _inc(p):
        grid[p] += 1
        if grid[p] > 9:
            queue.append(p)

    for step in range(1, 500):
        for point in grid:
            _inc(point)

        flashed = set()
        while queue:
            p = queue.popleft()
            if p in flashed:
                continue
            flashed.add(p)
            for neighbour in grid.get_neighbours(p, diag=True):
                _inc(neighbour)

        for point in flashed:
            grid[point] = 0

        flashes += len(flashed)
        if step == 100:
            a1 = flashes
        if len(flashed) == len(grid):
            return a1, step
    return -1, -1
예제 #6
0
def build_graph(data: str) -> tuple[nx.DiGraph, Point, Point, Point]:
    grid = Grid.from_number_string(data)
    original_x, original_y = max(grid)
    new_grid = grid.replicate(right=5, down=5)
    for x, y in new_grid:
        new_grid[x, y] += (x // (original_x + 1)) + (y // (original_y + 1))
        while new_grid[x, y] > 9:
            new_grid[x, y] -= 9
    return new_grid.to_graph(), (0, 0), (original_x, original_y), max(new_grid)
예제 #7
0
    def to_tile(self):
        tile_grid: Grid = Grid()
        for puzzle_point, tile in self.grid.items():
            stripped = tile.strip_border()
            scaled_point = (puzzle_point[0] * stripped.width, puzzle_point[1] * stripped.width)
            for child_point, value in stripped.grid.items():
                actual_point = add_points(scaled_point, child_point)
                tile_grid[actual_point] = value

        return Tile(-1, tile_grid, set())
def iterate_grid(grid: Grid, replace_fn: Callable[[Point, Grid], str]) -> Grid:
    new_grid = {}
    for (point, item) in grid.items():
        if not is_seat(item):
            new_grid[point] = item
            continue

        new_grid[point] = replace_fn(point, grid)

    return new_grid
예제 #9
0
def test():
    test_input = """2199943210
3987894921
9856789892
8767896789
9899965678"""
    grid = Grid(rows=((int(n) for n in row)
                      for row in test_input.splitlines()))
    answer_1 = part_one(grid)
    answer_2 = part_two(grid)
    assert answer_1 == 15, answer_1
    assert answer_2 == 1134, answer_2
예제 #10
0
def paint_hull(robot: IntcodeComp, start_white: bool) -> Tuple[Grid, int]:
    """
    Uses the specified robot to paint the hull of the ship
    :param robot: The Intcode programmed robot that paints the ship
    :param start_white: If the robot should begin on a white tile or black tile
    :return: A Tuple containing the resulting hull and amount of painted tiles
    """

    # Setup
    size: Final[int] = 150
    black: Final[str] = " "
    white: Final[str] = "▓"
    painted: Set[Vector] = set()
    direction: Direction = Direction.UP

    # Create hull
    position: Vector = Vector(size // 2, size // 2)
    hull: Grid[str] = Grid(size + 1, size + 1, black)
    # Set the starting tile to white if asked
    if start_white:
        hull[position] = white

    # Start the thread that the robot operates in
    thread: Thread = Thread(target=robot.run_program)
    thread.start()

    # Loop until the robot is done
    while True:
        # Input the current tile
        robot.add_input(int(hull[position] == white))
        # Wait for the output buffer to fill out (or the robot to be done)
        while thread.is_alive() and len(robot.output_buffer) < 2:
            time.sleep(1E-6)

        # If the robot shuts off, we are done
        if not thread.is_alive():
            break

        # Paint the new position accordingly
        hull[position] = white if bool(robot.next_output()) else black
        painted.add(position)
        # Move in the correct direction
        if bool(robot.next_output()):
            direction = direction.turn_right()
        else:
            direction = direction.turn_left()
        position = position.move_towards(direction)

    # Join the robot thread and return
    thread.join()
    return hull, len(painted)
예제 #11
0
def test():
    test_input = """5483143223
2745854711
5264556173
6141336146
6357385478
4167524645
2176841721
6882881134
4846848554
5283751526"""
    grid = Grid(rows=((int(n) for n in row)
                      for row in test_input.splitlines()))
    answer_1, answer_2 = both_parts(grid)
    assert answer_1 == 1656, answer_1
    assert answer_2 == 195, answer_2
예제 #12
0
def part_one(data: str) -> int:
    algo, grid = parse(data)
    for _ in range(2):
        print(f"{min(grid)=} {max(grid)=}")
        grid.add_padding(".")
        grid.print()
        new_grid = Grid(rows=[], pad_with=".")
        points = sorted(grid.points.keys(), key=lambda t: (t[1], t[0]))
        for p in points:
            neighbours = sorted(list(grid.get_neighbours(p, diag=True)) + [p],
                                key=lambda t: (t[1], t[0]))
            values = [str(grid[p]) for p in neighbours]
            bstr = "".join(values).translate(translator)
            new_value = algo[int(bstr, 2)]
            new_grid[p] = new_value
        grid = new_grid
    grid.print()
    return len([val for val in grid.points.values() if val == "#"])
예제 #13
0
def main(args: List[str]) -> None:
    """
    Application entry point
    :param args: Argument list, should contain the file to load at index 1
    """

    # File read stub
    with open(args[1], "r") as f:
        line = f.readline().strip()
        comp: IntcodeComp = IntcodeComp(line)

    # Count the amount of blocks
    blocks: int = 0
    size: Tuple[int, int] = 0, 0
    comp.run_program()
    while len(comp.output_buffer) >= 3:
        size = max(size, (comp.next_output(), comp.next_output()))
        blocks += 1 if comp.next_output() == 2 else 0
    print(blocks)

    # Setup the Intcode VM
    comp = IntcodeComp("2" + line[1:], threaded=True)
    thread: Thread = Thread(target=comp.run_program)
    thread.start()
    # Setup the play window
    game: Tk = Tk(screenName="Game")
    game.title("Block Game")
    # Setup the labels
    text: StringVar = StringVar()
    text.set("\n")
    Label(game, textvariable=text, font="Consolas").pack()
    score: StringVar = StringVar()
    score.set("Score: 0")
    Label(game, textvariable=score, font="Consolas").pack()
    # Setup the game grid
    grid: Grid[Block] = Grid(size[0] + 1, size[1] + 1)
    # Setup the update loop
    game.after(33, lambda: play(game, text, score, comp, grid))
    # Run the game
    game.mainloop()
    thread.join()
예제 #14
0
def parse(data: str) -> tuple[str, Grid[str]]:
    algo, grid_str = data.split("\n\n")
    grid = Grid(rows=grid_str.splitlines(), pad_with=".")
    return algo, grid
예제 #15
0
    return w_new / np.sum(w_new)


# Preduction step: sample from particles and perform prediction
def bootstrap(w, pos, ori, vel, om):

    new_p = np.searchsorted(np.cumsum(w), rng.uniform(size=w.shape))
    #new_p = np.arange(w.size)
    new_pos, new_ori = p_predict(pos[new_p], ori[new_p], vel, om)
    return w[new_p], new_pos, new_ori


#%% Set the grid map

# Initialise all data that we need
grid = Grid(0.15, [-25, 25], [-25, 25], np.array((0.0, )))
n_particles = 50
p_position = np.zeros(shape=(n_particles, 2, n_steps + 1))
p_velocity = np.zeros(shape=n_steps + 1)
p_orientation = np.zeros(shape=(n_particles, 1, n_steps + 1))
p_accepted_position = np.zeros(shape=(2, n_steps))
p_accepted_orientation = np.zeros(shape=(1, n_steps))
p_weight = np.ones(shape=(n_particles, n_steps + 1)) / float(n_particles)
#%%
lidar_angle_increment_deg = lidar_angle_increment * 180.0 / np.pi
angles = -1 * np.arange(-135.0, 135.0 + lidar_angle_increment_deg,
                        lidar_angle_increment_deg) * np.pi / 180.0

# Initialise Grid with the first map that we have
grid.reset()
lidar_idx = np.argmin(np.abs(-dT - lidar_stamps))
예제 #16
0
    #normalizo la imagen
    im -= im.mean()
    im /= (im.std() + 1e-5)  #por si tengo cero
    im *= desv
    #la llevo a 8 bits
    im *= 64
    im += 128
    im = np.clip(im, 0,
                 255).astype('uint8')  #corta todo por fuera de la escala
    return im


#%%

activations = np.load('activations.npz')
activations = [v for v in activations.values()]

for layer_activation in activations:  #zip simplemente me da dos iteradores

    n_features = layer_activation.shape[-1]  #cant de filtros
    size = layer_activation.shape[
        1]  #tamaño del filtro de la capa (es cuadrado)

    g = Grid(n_features, fill_with=0)
    for ch_image in range(n_features):
        channel_image = layer_activation[0, :, :, ch_image]
        g.insert_image(bitificar8(channel_image, 2))

    g.show()
    #    plt.title('{0}: {1}x{1}'.format(layer_name,size-1))
    plt.grid(False)
예제 #17
0
def part_one(grid: Grid) -> int:
    return sum(val + 1 for _, val in grid.search(mindepth))
예제 #18
0
def part_two(grid: Grid) -> int:
    low_points = [p for p, v in grid.search(mindepth)]
    sizes = []
    for lp in low_points:
        matches = list(grid.collect_recursive([lp], notnine))
        sizes.append(len(matches))
    top3 = sorted(sizes, reverse=True)[:3]
    return math.prod(top3)


def test():
    test_input = """2199943210
3987894921
9856789892
8767896789
9899965678"""
    grid = Grid(rows=((int(n) for n in row)
                      for row in test_input.splitlines()))
    answer_1 = part_one(grid)
    answer_2 = part_two(grid)
    assert answer_1 == 15, answer_1
    assert answer_2 == 1134, answer_2


if __name__ == "__main__":
    test()
    data = aocd.get_data(day=9, year=2021).splitlines()
    grid = Grid(rows=((int(n) for n in row) for row in data))
    print("Part 1: ", part_one(grid))
    print("Part 2: ", part_two(grid))
예제 #19
0
def CalLinearDeriv(moving, fixed, vgrad, vgrid, skip):
    # NEED TO IMPLEMENTATION
    assert(moving.size == fixed.size)

    (gysize, gxsize) = vgrid.size
    (ysize, xsize) = fixed.size

    spacing = vgrid.spacing
    origin = vgrid.origin
    deriv = Grid(moving.size, spacing)

    for gy in range(gysize - 1):
        py =  spacing[1] * gy + origin[1]
        ymin = max(py, 0)
        ymax = min(py + spacing[1], ysize)
        for gx in range(gxsize - 1):
            px = spacing[0] * gx + origin[0]
            xmin = max(px, 0)
            xmax = min(px + spacing[0], xsize)

            # Add to deriv grid (gx,gy), (gx,gy+1), (gx+1,gy), (gx+1,gy+1)
            a00, a01 = np.array([0.0, 0.0]), np.array([0.0, 0.0])
            a10, a11 = np.array([0.0, 0.0]), np.array([0.0, 0.0])

            v00 = vgrid.values[gy  , gx  ]
            v01 = vgrid.values[gy  , gx+1]
            v10 = vgrid.values[gy+1, gx  ]
            v11 = vgrid.values[gy+1, gx+1]

            for y in range(ymin, ymax, skip):
                ry = (y - py) / float(spacing[1])
                for x in range(xmin, xmax, skip):
                    rx = (x - px) / float(spacing[0])
                    v0 = (1 - rx) * v00 + rx * v01 
                    v1 = (1 - rx) * v11 + rx * v10
                    v  = (1 - ry) * v1  + ry * v0
                    coord = np.array([x, y]) + v

                    # Find value in fixed
                    g = linear_interpolator(moving, coord)
                    
                    # For out of bound
                    if g < 0.0:
                        g = 0.0
                    if g > 1.0:
                        g = 1.0

                    flag = np.sign(g - fixed.values[y, x])
                    # Find value in vgrad
                    tmp_grad = linear_interpolator(vgrad, coord) * flag

                    a00 += (1 - rx) * (1 - ry) * tmp_grad
                    a01 += (rx    ) * (1 - ry) * tmp_grad
                    a10 += (1 - rx) * (ry    ) * tmp_grad
                    a11 += (rx    ) * (ry    ) * tmp_grad

                    # print g, rx, ry, 1-rx, 1-ry, flag, tmp_grad, a00, a01, a10, a11

            deriv.values[gy  , gx  ] += a00
            deriv.values[gy  , gx+1] += a01
            deriv.values[gy+1, gx  ] += a10
            deriv.values[gy+1, gx+1] += a11

    deriv.values = deriv.values / (xsize * ysize / (skip**2))
    return deriv
예제 #20
0
 def __init__(self, id: int, grid: Grid, matched_edges: Set[str]):
     self.id = id
     self.grid = grid
     self.width = int(math.sqrt(len(grid)))
     self.sorted_points = sorted(grid.keys())
     self.matched_edges = matched_edges
예제 #21
0
    # Carpeta donde guarda las imagenes de los filtros
    # save_dir = make_dirs_noreplace(os.path.join(
    #         'filtros', os.path.splitext(nombre_modelo)[0]))
    save_dir = os.path.join(carpeta, 'filtros')
    os.makedirs(save_dir)

    # Itero sobre todos los filtros de las capas convolutivas
    for capa_ind, nombre in enumerate(nombres):
        print('Corriendo capa ' + nombre)

        # Cantidad de filtros en esta capa
        cant_filtros = modelo.layers[capa_ind].output_shape[
            3]  #cant de filtros
        # Una grilla donde meto las imagenes de cada filtro
        g = Grid(cant_filtros, fill_with=np.nan, trasponer=True)

        # Proceso los filtros y los meto en la grilla
        for filtro_ind in range(cant_filtros):
            channel_filter = generate_pattern(nombre, filtro_ind, modelo)
            channel_filter = np.squeeze(channel_filter)

            # channel_filter es la imagen en cuestión
            g.insert_image(channel_filter)

        # plt.imshow(g.grid)
        g.show()
        nombre = new_name(
            os.path.join(save_dir, 'filtros_{}.jpg'.format(nombre)))
        plt.savefig(nombre, bbox='tight', dpi=400)
        plt.close()
예제 #22
0
    #miro alguna activación
    activations = activation_model.predict(una_imagen)
    #first_layer_activation = activations[0] #primera capa
    #print(first_layer_activation.shape) #pinta de los filtros de la capa
    #plt.matshow(first_layer_activation[0, :, :, 0], cmap='viridis') #quito filtro

    layer_names = [l.name for l in modelo.layers if 'conv' in l.name]

    for layer_name, layer_activation in zip(
            layer_names, activations):  #zip simplemente me da dos iteradores

        n_features = layer_activation.shape[-1]  #cant de filtros
        size = layer_activation.shape[
            1:3]  #tamaño del filtro de la capa (es cuadrado)

        g = Grid(n_features, fill_with=np.nan, bordes=True)
        for ch_image in range(n_features):
            channel_image = layer_activation[0, :, :, ch_image]
            g.insert_image(bitificar8(channel_image, 2))

        g.show()
        plt.title('{}: {}x{}'.format(layer_name, *size))
        plt.grid(False)
        plt.savefig(os.path.join(carpeta_de_guardado, layer_name + '.jpg'),
                    bbox='tight',
                    dpi=400)
        plt.close()

print('\a')