Add solution for "Day 12: Garden Groups", part 2

This commit is contained in:
2025-02-17 15:23:55 +01:00
parent f3682a46a9
commit 5b15e36bc5
3 changed files with 54 additions and 15 deletions

View File

@@ -53,6 +53,7 @@ void GardenGroups::traverseRegion(Grid<bool>& isVisited, std::stack<Point2>& oth
const char plantType{ getCharAt(start) };
long long int area{ 0 };
long long int perimeter{ 0 };
long long int nCorners{ 0 };
std::stack<Point2> regionStack{};
regionStack.push(start);
@@ -65,34 +66,54 @@ void GardenGroups::traverseRegion(Grid<bool>& isVisited, std::stack<Point2>& oth
isVisited.cell(position) = true;
area++;
Point2 previousNeighbor{ position + Point2::cardinalDirections.back() };
bool isPreviousNeighborSameRegion{
isInBounds(previousNeighbor) && getCharAt(previousNeighbor) == plantType
};
for (const Point2& direction : Point2::cardinalDirections)
{
const Point2 next{ position + direction };
if (isInBounds(next))
const Point2 neighbor{ position + direction };
const bool isNeighborSameRegion{ isInBounds(neighbor) && getCharAt(neighbor) == plantType };
if (isNeighborSameRegion)
{
if (getCharAt(next) == plantType)
if (!isVisited.cell(neighbor))
{
if (!isVisited.cell(next))
{
regionStack.push(next);
}
regionStack.push(neighbor);
}
else
// Increases the corner count if two adjacent neighbors are both inside this region, but the
// diagonal neighbor in between them is outside this region.
if (isPreviousNeighborSameRegion)
{
perimeter++;
if (!isVisited.cell(next))
const Point2 diagonalNeighbor{ previousNeighbor + direction };
if (!isInBounds(diagonalNeighbor) || getCharAt(diagonalNeighbor) != plantType)
{
otherRegionsStack.push(next);
nCorners++;
}
}
}
else
{
if (isInBounds(neighbor) && !isVisited.cell(neighbor))
{
otherRegionsStack.push(neighbor);
}
perimeter++;
// Increases the corner count if two adjacent neighbors are both outside this region.
if (!isPreviousNeighborSameRegion)
{
nCorners++;
}
}
previousNeighbor = neighbor;
isPreviousNeighborSameRegion = isNeighborSameRegion;
}
}
}
part1 += area * perimeter;
part2 += area * nCorners;
}