In Advent of Code Day 8 we are looking at a grid and comparing the heights of trees in four directions, along the column and row, first to determine visibility, and then to calculate a “scenic score” (how many trees can be seen in each direction).
I am playing catch-up, having missed two days, so this one is going to be kept simple (in C++).
I start this one with some unit tests, one matching the example from the puzzle description, and a few smaller tests to make sure the edge cases are properly handled:
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FAoC2022D08_Test, "AOC.2022.D08", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter)
bool FAoC2022D08_Test::RunTest(FString const& Parameters)
{
TArray< FString > OneTree = {
TEXT("1"),
};
TestEqual(TEXT("One Tree"),
UAoC22BPFunctionLibrary::D08_CalculateVisibility(OneTree), 1);
TArray< FString > EdgeOnlyCase = {
TEXT("33"),
TEXT("22"),
};
TestEqual(TEXT("Edge Only: 4 Trees"),
UAoC22BPFunctionLibrary::D08_CalculateVisibility(EdgeOnlyCase), 4);
TArray< FString > Eight = {
TEXT("222"),
TEXT("222"),
TEXT("222"),
};
TestEqual(TEXT("3x3, 1 hidden (Eight)"),
UAoC22BPFunctionLibrary::D08_CalculateVisibility(Eight), 8);
TArray< FString > TestCase = {
TEXT("30373"),
TEXT("25512"),
TEXT("65332"),
TEXT("33549"),
TEXT("35390")
};
TestEqual(TEXT("21"),
UAoC22BPFunctionLibrary::D08_CalculateVisibility(TestCase), 21);
return true;
}Then the implementation. Given the 99*99 grid, there is not need to try anything complex, this problem can be brute-forced in C++:
int UAoC22BPFunctionLibrary::D08_CalculateVisibility(const TArray<FString>& Input)
{
const int GridDX = Input.Num();
const int GridDY = Input[0].Len();
int Total = 0;
const FIntPoint Scan[]
{
{1,0}, {-1,0}, {0,1}, {0,-1},
};
for (int X = 0; X!=GridDX; ++X)
{
ensure(Input[X].Len()==GridDY);
for (int Y = 0; Y!=GridDY; ++Y)
{
const int T = Input[X][Y];
for (int S=0;S!=4;++S)
{
bool Occluded = false;
FIntPoint P2 = {X,Y};
P2 += Scan[S];
// while in bounds and not blocked
while(P2.X>=0 && P2.Y>=0 && P2.X<GridDX && P2.Y<GridDY && !Occluded)
{
if (Input[P2.X][P2.Y] >= T)
Occluded = true;
P2 += Scan[S];
}
if (!Occluded)
{
Total++;
break;
}
}
}
}
return Total;
}For Part 2 we calculate a “scenic score” for each tree. The example gives us one new unit test:
TestEqual(TEXT("Scenic Score"),
UAoC22BPFunctionLibrary::D08_CalculateScenicScore(TestCase), 8);I copy-pasted Part 1 into a new function and edited it:
int UAoC22BPFunctionLibrary::D08_CalculateScenicScore(const TArray<FString>& Input)
{
const int GridDX = Input.Num();
const int GridDY = Input[0].Len();
int Total = 0;
const FIntPoint Scan[]
{
{1,0}, {-1,0}, {0,1}, {0,-1},
};
for (int X = 0; X!=GridDX; ++X)
{
ensure(Input[X].Len()==GridDY);
for (int Y = 0; Y!=GridDY; ++Y)
{
const int T = Input[X][Y];
int Score[4]={0,0,0,0};
for (int S=0;S!=4;++S)
{
FIntPoint P2 = {X,Y};
P2 += Scan[S];
int TreesSeen = 0;
// while in bounds
while(P2.X>=0 && P2.Y>=0 && P2.X<GridDX && P2.Y<GridDY)
{
TreesSeen+=1;
if (Input[P2.X][P2.Y] >= T)
break;
P2 += Scan[S];
}
Score[S]=TreesSeen;
}
const int ScoreCombo = Score[0]*Score[1]*Score[2]*Score[3];
if (ScoreCombo>Total)
{
Total=ScoreCombo;
}
}
}
return Total;
}Which worked first time.

1 thought on “Advent of Code in Unreal Engine Day 8”