AoC 2024/15: 🎄 The Misadventures of the Lanternfish Warehouse Robot 🎅
🎄 The Misadventures of the Lanternfish Warehouse Robot 🎅
We’re deep under the ocean in our mini-submarine (again!), when the glow of a school of lanternfish catches your eye.
It turns out that these industrious lanternfish have built an elaborate network of warehouses to store food for their ever-growing population. Unfortunately, disaster has struck! A malfunctioning robot is wreaking havoc in one of their most critical warehouses, pushing boxes around with reckless abandon.
🐟 The Problem
The warehouse is represented as a grid where:
#
marks walls..
represents empty spaces.@
is the robot’s current position.O
marks the locations of boxes.
The robot moves according to a set of instructions (<
, >
, ^
, v
), attempting to:
- Move in the specified direction.
- Push any box (
O
) in its path, provided there is space behind it. - Do nothing if a move would cause the robot or a box to collide with a wall (
#
) or another box.
An example looks like this:
|
|
Our task is to simulate the robot’s movement and calculate the sum of all box GPS coordinates once the robot has finished its instructions.
The GPS Coordinates can be calculated using:
GPS Coordinate=100×row distance+column distance
Personally I love these grid problems, as it allows for graphical debugging and they are generally easier to brute-force, as a non-professional programmer.
🎁 Part 1
The challenge starts with a regular warehouse layout and the robot’s list of movements. Using Python, we simulate each move, accounting for:
- Box movement (or blockage by walls or other boxes).
- Robot positioning.
- Calculating the GPS coordinates of boxes at the end.
0. Helper functions
As mentioned, I have helper functions for grid work.
File to grid
|
|
Adding tuples
|
|
Get grid values
I’m not listing the whole function, as it can be found on my [gitea repo][https://gitea.baerentsen.space/FrederikBaerentsen/AdventOfCode/src/branch/master/fred.py]. But the main idea can be seen here.
|
|
1. Setting Up the Warehouse
The next thing we do is load the warehouse layout and identify the starting position of the robot (@
).
|
|
- The
grid
represents the warehouse as a 2D array of characters (#
,.
,O
,@
). - We loop through the grid to find the robot’s starting coordinates (
start
).
2. Moving the Robot
Each movement (<
, >
, ^
, v
) is processed one by one. The robot attempts to move in the specified direction. We define a dictionary to map directions to their respective coordinate changes:
|
|
The robot’s logic for handling moves is as follows:
-
Check the space in the desired direction:
- If it’s a wall (
#
), the robot stays put. - If it’s empty (
.
), the robot moves there. - If it’s a box (
O
), the robot attempts to push it.
- If it’s a wall (
-
Handling box pushing:
- The robot checks if the box can be moved (i.e., if the space behind it is empty).
- If the box can move, it’s pushed into the empty space, and the robot moves into the box’s previous position.
Here’s the box-pushing logic in action:
|
|
This ensures the robot pushes the box properly while respecting boundaries.
3. Calculating the GPS Sum
After processing all the moves, we calculate the GPS coordinates for all remaining boxes (O
). The formula is:
[ \text{GPS Coordinate} = 100 \times \text{row index} + \text{column index} ]
|
|
This loop iterates through the final grid, adding up the GPS values for all boxes.
Final Grid Visualization
As the robot moves, we can print out the grid to track its progress, which is helpful for debugging or just appreciating the chaotic beauty of the robot’s path:
|
|
🎁 Part 2: Expanding the Warehouse
For Part 2, the lanternfish reveal that the warehouse has a scaled-up version where everything (except the robot) is twice as wide:
- Walls (
#
) become##
. - Boxes (
O
) become[]
. - Empty spaces (
.
) become..
.
This change means boxes can now align side-by-side and be pushed together. To solve this, the program needed to:
- Adjust for the expanded grid.
- Ensure box movements accounted for their increased size and alignment.
Scaling Up for Part 2
In Part 2, the lanternfish introduce a scaled-up warehouse where:
- Walls (
#
) are doubled into##
. - Boxes (
O
) become[]
to represent their increased size. - Empty spaces (
.
) become..
.
When reading part 2, my immediate thought was how hard can that be, followed by viewing the example and changing my mind to I’m skipping Part 2 today. I decided to try my luck with a slightly changed Part 1 code and hope for the best.
1. Resizing the Grid
We start by transforming the grid into its scaled-up version. Each tile is expanded horizontally:
|
|
This creates a new grid that is twice as wide as the original.
2. Adapting the Robot’s Movements
The robot logic from Part 1 remains the same, but now it must account for the fact that boxes ([]
) take up two spaces. For example:
- When the robot pushes a box, it must check both spaces of the box.
- If the box moves, both spaces must be updated accordingly.
To check which boxes can move, we can recursively go through the boxes:
|
|
To move the boxes we call:
|
|
What caused me a bit of a headache was a case like this:
|
|
Here we get a list like [(4,6),(4,7),(3,5),(3,6),(3,7),(3,8)]
and going through the list we first move (4,6)
and the grid becomes:
|
|
The rest of the numbers follow:
|
|
|
|
This is all sorts of wrong!
But it can easily be solved using boxes = sorted(boxes, reverse=(direction == 'down'))
such that we move the lowest value boxes first when going up and highest value boxes when going down.
3. Calculating the GPS for Wide Boxes
For wide boxes ([]
), the GPS coordinate is based on the closest edge of the box:
[ \text{GPS Coordinate} = 100 \times \text{row index} + \text{column index of left edge} ]
This is an incredible easy change, as we just replace the search for O
with [
.
Holiday Wrap-Up
The lanternfish are thrilled, and the malfunctioning robots are finally under control. The warehouse glows with festive lights as the lanternfish celebrate your heroic efforts.
My complete Advent of Code can be found on my Gitea page https://gitea.baerentsen.space/FrederikBaerentsen/AdventOfCode
Happy coding, and Merry Christmas! 🎄