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:
Language
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.
Library
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
Template
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):
pass
print(part_one(test_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.
Logex
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!
Finish
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:
- Day 24 - Arithmetic Logic Unit (actually do it)
- Day 23 - Amphipod
- Day 22 - Reactor Reboot (rework my brute force and clean up)
- Day 19 - Beacon Scanner (clean up, very untidy)
- Day 17 - Trick Shot (use a better way to determine range of value to search)
- Day 14 - Extended Polymerization (cleanup)
test_input_str = """v...>>.vv> .vv>>.vv.. >>.>v>...v >>v>>.>.v. v>v.vv.v.. >.>>..v... .vv..>.>v. v.v..>>v.v ....v..v.>""" 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")] @listify 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 == ".": continue elif col != herd_type: new_grid[r][c] = col else: 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 else: 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