Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes

2021-12-25 - Sea Cucumber

(original .ipynb)

Day 25 puzzle input is a grid showing the position and direction that some sea cucumbers are (mine is here) - where . is an empty space, > is an east-facing sea cucumber, v is a south-facing sea cucumber. There are some rules that govern how they can move around the grid (east-facing move before south-facing, if you go off the bottom or right of the grid you wrap around). Part 1 involves finding how many "steps" it takes to reach a state where no cucumber can move. There is no Part 2.

Before the solution itself, a quick summary of Advent of Code 2021:


While the first 5-6 days are potentials for getting a top-100 finish if I really practiced and stuck with Python ... I don't think I'm getting much out of it. I should definitely explore something new next year, like OCaml. It's still sort of fun in Python (and removes a bit of cognitive load in the harder ones) but until the mid-teens everything is pretty straight-forward.


This year the advent library I built up over the years was not particularly useful - it was nice to be able to use the graphic capabilities I built up ... but the rest was hopeless. I sort of forced it


I came up with a little template I pasted into each day so that when I started on a challenge I wasn't staring at a blank page, there were a couple of mechanical steps to get me into the right state of mind (pasting the test and puzzle input into the right place, then writing the parser) and I could largely focus on the problem rather than writing some boilerplate code.

    test_input_str = """"""
    puzzle_input_str = open("puzzle_input/day19.txt").read()

    def part_one(input_str):


    assert XXX == part_one(test_input_str)
    print("part one:", part_one(puzzle_input_str))

3D problems

For some reason I really struggled with the problems that involved thinking in 3D. Days 19 and 22 had me completely stunlocked for a while, after a few hours of procrastinating after I saw the problem itself.


The Logex community effort was outstanding. I didn't try to push anyone to try AoC that much, but there were still a lot of people who kicked off and a few of us were pretty active and helping each other figure out the solutions or understanding the problems. I'm really impressed by Martin Pieck's effort in catching up something 10 problems within the space of a few daysafter a little later than the rest of us!


It's a bit of a shame I didn't finish it all on the 25th. Day 24 really broke me, I just couldn't see the real problem until Rob spelled it out for me.

Revisiting problems

There are still a couple of solutions I want to come back to:

test_input_str = """v...>>.vv>
puzzle_input_str = open("puzzle_input/day25.txt").read()

from advent import listify

def parse_input(input_str):
    return [list(line.strip()) for line in input_str.strip().split("\n")]

def blank_grid(grid):
    for row in grid:
        yield ["."] * len(row)

def next_position(grid, r, c, dr, dc):
    r = (r + dr) % len(grid)
    c = (c + dc) % len(grid[r])    
    return r, c

move_vector = {
    ">": (0, 1),
    "v": (1, 0),

def step(grid, herd_type):
    new_grid = blank_grid(grid)
    moved = 0
    for r, row in enumerate(grid):
        for c, col in enumerate(row):
            if col == ".":
            elif col != herd_type:
                new_grid[r][c] = col
                dr, dc = move_vector[col]
                nr, nc = next_position(grid, r, c, dr, dc)
                if grid[nr][nc] == ".":
                    new_grid[nr][nc] = col
                    moved += 1
                    new_grid[r][c] = col
    return new_grid, moved

def part_one(input_str):
    grid = parse_input(input_str)
    steps = 0
    moved = 1
    while moved > 0:
        grid, moved_east = step(grid, ">")
        grid, moved_south = step(grid, "v")
        moved = moved_east + moved_south
        steps += 1

    return steps

assert 58 == part_one(test_input_str)
print("part one:", part_one(puzzle_input_str))
part one: 534