Advent of Code - Day 12: Garden Groups
Overview
The GridSolver class is tasked with:
- Reading the garden grid from a file.
- Identifying different regions (connected garden plots of the same type).
- Calculating the area and perimeter (or number of sides) of each region.
- Summing up the total fencing cost for all regions, with two different methods (for Part 1 and Part 2).
Breakdown of the Key functions are:
FindAllRegions Function
This function loops through every cell in the grid and calls FindRegion
for any cell that has not already been visited. It collects all regions (sets of connected plots).
FindRegion Function
This is a recursive function that finds all connected garden plots of the same type (region). Starting from a given cell (identified by row and col), it explores the grid in four directions (up, down, left, right) and collects all the points in that region, using my Helper Directions
class.
Importantly, it uses a HashSet<>
to track the points already visited to avoid infinite loops or redundant calculations (already seen plots).
Part1 Function
This function calculates the cost for all regions using the formula area × perimeter
. The perimeter is calculated by checking each garden plot in a region and counting how many sides are exposed (i.e. not touching another plot in the same region).
Part2 Function
In Part 1, we calculated the fence cost for each region by using the perimeter, which was the total number of edges of garden plots that don’t touch other plots in the same region. However, in Part 2, we are asked to calculate the cost by considering the number of sides (not just the perimeter). This means counting every side of the garden plots that belong to a region, even the internal borders between regions.
Corners:
When you think of a garden plot (a square), it has four corners (at the intersections of its edges).
A corner is considered part of the region if the garden plot is adjacent to another plot of the same region on at least two of its four sides.
For example, if two plots meet at a corner but aren’t part of the same region, that corner is counted as a corner contributing to the fence because it’s an "exposed" corner where the regions don’t connect.
Inside and Outside:
For a plot in the interior of a region (i.e. a plot surrounded by other plots of the same type), the sides connecting to other plots don’t count for fencing, because those sides are "inside" the region and won’t be exposed to the outside. Think about if you had fake grass in your yard. Each tile is INSIDE your region (backyard), so doesn't need a fence around each tile (plot).
For a plot on the outside of a region (i.e., a plot at the boundary of the region), its sides that are not touching another plot of the same region do count for the fencing.
So, the "outside" sections of a region contribute to the fencing calculation because they form the boundary of that region. The "inside" sections of a region don’t contribute to the fence.
Counting the Number of Sides
Let’s focus on how we can calculate the number of sides in Part 2 using this inside and outside approach:
For each region:
The area of the region is the number of garden plots in it.
The number of sides is calculated by checking each plot in the region.
For each plot:
If a side is touching another plot of the same region, it doesn’t count as part of the fencing.
If a side is touching a plot of a different region it does count as part of the fencing.
To account for corners:
For each corner in a plot, we check how many of the adjacent plots belong to the same region.
If exactly one side of the corner is part of the same region, the corner adds 1 to the fence count.
If exactly three sides of the corner belong to the same region, that’s an internal corner that does not contribute to the fence (because it's entirely surrounded by the same region).
If the corner belongs to different regions (like a corner shared between two regions), it is counted as contributing to the fence.
Once we have all the sides counted, we can then multiply this by the area, and voila - we have our new discounted cost.
Conclusion
I hope this explanation along with the code can help you solve this problem, or future challenges. As always drop me a follow , and you can always reach out to me on Twitter
Top comments (0)