Metadata
-
Date
-
Tagged
-
Part of series
- Advent of Code 2023 Day 1
- Advent of Code 2023 Day 2
- Advent of Code 2023 Day 3
- Advent of Code 2023 Day 4
- Advent of Code 2023 Day 5
- Advent of Code 2023 Day 6
- Advent of Code 2023 Day 7
- Advent of Code 2023 Day 8
- Advent of Code 2023 Day 9
- Advent of Code 2023 Day 10
- Advent of Code 2023 Day 11
- Advent of Code 2023 Day 12
- Advent of Code 2023 Day 13
- Advent of Code 2023 Day 14
- Advent of Code 2023 Day 15
- Advent of Code 2023 Day 16
- Advent of Code 2023 Day 17
- Advent of Code 2023 Day 18
- Advent of Code 2023 Day 19
- Advent of Code 2023 Day 20
- Advent of Code 2023 Day 21
- Advent of Code 2023 Day 22
- Advent of Code 2023 Day 23
- Advent of Code 2023 Day 25
-
Older post
-
Newer post
Advent of Code 2023 Day 21
Day 21: Step Counter
https://adventofcode.com/2023/day/21
After fixing the sand supply, you visit the gardener again.
An elf heard of your exploits and wants your help.
Today’s input is a map of the gardens.
An example input looks like this:
#
is a rock.
is a gardenS
is your starting position
Your starting position is also a garden.
The elf would like to know how many tiles they can reach in a given amount of steps.
Each step the elf can move up/down/left/right given that there is no rock in the way.
Backtracking is allowed, so the elf could go left/right forever if it wants to.
Parsing
I went very imperative today as it was the first thing that came to mind, and it works!
I parse the 2D grid of Tile
and a starting Coord
.
Part 1
The Elf actually needs to get 64 steps today.
Starting from the garden plot marked S on your map, how many garden plots could the Elf reach in exactly 64 steps?
Helpers
A method on a Coord
that returns every neighbour in the grid:
I kept track of the locations that could be visited in the same amount of steps in a set.
For each amount of steps, for each position in the set, I inserted every possible neighbour into a new set.
Before moving on to the next step, I update the old set to point to the new set.
Code
Part 2
Oopsie, turns out the grid is infinitely repeating in every direction. Something, something, magic.
And the number of steps the elf gave you was also wrong, it should have been 26501365.
Helpers
This infinity business means the helpers I wrote are wrong.
A Coord
should hold integers that can be negative.
And the neighbour logic is no longer limited by puny limits:
This also means the parsing logic is slightly different, the part where I set the starting coordinate should now set signed integers instead of unsigned ones.
I read someone’s solution, translated it to Rust, and tried to understand it as best I could.
This part requires some investigation of the input again. It uses some properties of the input that are NOT ALL PRESENT in the example input.
- The input is a square with an odd numbered size
- The starting location is in the perfect middle of the square
- All tiles on the starting row are gardens
- All tiles on the starting column are gardens
This means that the quickest way to reach any edge is half of (the size of the square - 1).
It turns out that all the properties combined let you represent the amount of positions reachable in a certain amount of steps with a function. A quadratic function.
- Let be the number of spaces you can reach after an amount of steps.
- Let be the length of the input grid.
- Let be the amount of steps needed to reach the edge of that grid
, , , … are all quadratic functions.
You can find that function by finding 3 values and then calculating which quadratic function satisfies all 3.
In our code we keep track of the first 3 values: the results to those 3 functions I wrote above.
What the question is looking for is .
And
Only is unknown here, plugging in the known numbers:
So
With all those numbers known calculating becomes, as my high-school math teacher would say, trivial.
Ugh, I just felt a pang of anger even typing those words.
Nearly every time that word is said, it’s a lie.
It was then, and it certainly is now.
And to repeat, I most certainly didn’t do this myself.