Day 14: Regolith Reservoir
https://adventofcode.com/2022/day/14
The distress signal you received yesterday came from a cave behind a waterfall.
The cave is slowly filling with sand!
Your device scans the cave.
Today’s input file is the list of rock edges.
An example input looks like this:
Every rock formation has perfectly square edges.
Between every edge it returned, you can draw a straight line, every point on the line is also a rock.
This scan means that there are two paths of rock.
- The first path consists of two straight lines
- The second path consists of three straight lines.
- A unit of sand is big enough to fill one coordinate.
- A unit of sand has to come to a rest before an other one starts falling.
- The source of sand is at coordinates
x=500
, and y=0
.
For every position sand is in, a sequence of checks are done to determine where it goes next, or if it stays put:
- Sand goes straight down one step.
- If that position is blocked, it goes down and to the left instead.
- If that position is blocked, it goes down and to the right instead.
- If that position is blocked, the sand comes to a rest.
Every unit of sand continues falling until it comes to a rest.
At that point, the next unit of sand starts falling.
Parsing
Good news everyone, the Coord
struct is back to represent a coordinate in our square grid.
I parsed the input into a list of lists.
Each item is a list containing rock edge coordinates.
Part 1
You don’t know what’s underneath the lowest point of your scan, you assume it’s an endless abyss.
The question asks how many units of sand came to a rest before sand starts falling into the abyss.
in pseudocode:
Helpers
Every tile in the cave grid can be in 3 possible states:
- It’s air
- It’s a rock
- It’s sand
I’ll construct the cave
in two steps.
- create a collection of every rock coordinate in the cave.
- create the cave as 2D list. Where every item in the outer list is a row, and every row is a list of
Tile
.
To create the cave from that
A piece of sand has a Coord
.
If it falls, it falls in one of three spots.
I call those possible spots the neighbours
of a Coord
.
When a piece of sand falls, it follows the rules mentioned at the top.
Falling into the place of the first neighbour it can.
This way of checking for a possible next position of falling sand is perfect to adjust our pseudocode to use a while let
loop.
Final code
Part 2
There was no abyss!
The floor is 2 tiles underneath the lowest rock in your scan.
It appears to be infinite.
The question asks how many units of sand came to a rest when the entry at x=500, y=0 is blocked.
A few additions to the code!
The next
method on Coord
needs to check if a unit of sand hits the floor.
It can’t move down further once it does, so it comes to rest.
The condition where the code stops looping changed too.
The one from part1 is removed, and a return is added at the end of the infinite loop.
It checks if the sand is at the beginning after it came to rest.
Final code
Optimization
A possible optimization is to keep track of empty positions while a unit of sand is falling.
Every subsequent unit of sand will follow the same path as the previous one until it is blocked.
I added it to the simulate
function below and commented what’s happening.
Final code