I’m only keeping the positions an elf is in memory.
Every elf has a Coord, and the result of parsing the input as a set of them.
The Coord struct uses numbers that can go negative.
Because the elves can move off the map in the input to the top or to the left.
Part 1
The elves use a time-consuming method to spread out.
After 10 full rounds of this method, the elves like to check if they’re on the right track.
Draw a box from the top-left elf to the bottom-right one.
The question asks how many empty spaces are in the box.
The process consists of three phases per round:
The consideration phase
The movement phase
The swappy-checky phase (I couldn’t come up with a name, ok?)
The consideration phase
Each Elf considers their 8 adjactent neighbours.
A quick sidebar I like to call “we’re making a data type”.
It’s the Direction enum!
If no other Elves are in one of those eight positions, the Elf does not do anything during this round.
Otherwise, the Elf looks in each of four directions in the following order and proposes moving one step in the first valid direction:
If there is no Elf in the N, NE, or NW adjacent positions, the Elf proposes moving north one step.
If there is no Elf in the S, SE, or SW adjacent positions, the Elf proposes moving south one step.
If there is no Elf in the W, NW, or SW adjacent positions, the Elf proposes moving west one step.
If there is no Elf in the E, NE, or SE adjacent positions, the Elf proposes moving east one step.
The movement phase
All at once, each Elf moves to their proposed destination tile if they were the only Elf to propose moving to that position.
If two or more Elves proposed moving to the same position, none of those Elves move.
The swappy-checky phase
This is the part that changes the order of those 4 checks in the consideration phase.
The first round starts by checking the cardinal directions as they appear in the text.
First North, then South, followed by West, and finally East.
Here, the first direction in that list moves to the back.
So the second round would start by checking South, then West, followed by East, and finally North.
Helpers
A few helpers for the Coord struct that let us take one step in a given Direction.
That’s also handy to find a Coord’s 8 neighbours.
And a helper on Direction that, given a list of 8 neighbour occupation booleans says if the corresponding check succeeds.
The check from the consideration phase.
There’s 1 check for North, 1 for South, 1 for West, and 1 for East.
As a bonus, a function to print out the current map.
It gets the min and max value for the row coordinate of every elf.
It gets the min and max value for the col coordinate of every elf.
It then loops through the rows and cols. And prints something depending if an elf was found at that combination of row and col.
# if an elf is there
. if the space is open
Don’t forget to print a newline after every row, or the output will be one big lne.
Skeleton code time!
Scratch that, with these helpers, implementation time!
Final code
Part 2
Eventually, the elves come to a stop.
The question asks for the round number where no elf moves.
A moved boolean that starts at false, and flips to true every time an elf moves.
If it’s still false at the end of a round, done!