Day 06 of Advent of Code, and after yesterdays Blueprints it’s time for a C++ palate cleanser with a side order of Unit Testing.
The problem consists of sub-string character uniqueness checking. I appreciate that this solution can be optimized but it is fast enough for the size of the puzzle input so it’ll do.
// added to AoC22BPFunctionLibrary.h
// Find the fist location in the string where the preceding L characters are not repeated
UFUNCTION(BlueprintCallable)
static int FindStartOfPackerMarker(const FString& Input, int L=4);
// added to AoC22BPFunctionLibrary.cpp
bool UniqueInSpan(int c, int a, int b, const FString& Input)
{
for(int i=a;i!=b;++i)
if (Input[i]==c) return false;
return true;
}
int UAoC22BPFunctionLibrary::FindStartOfPackerMarker(const FString& Input, int L)
{
const int e = Input.Len() - L;
for (int i=0;i!=e;++i)
{
bool NonUnique = false;
for (int j=0;j!=L;++j)
{
if (!UniqueInSpan(Input[i+j],i+j+1,i+L, Input))
{
NonUnique = true;
break;
}
}
if (NonUnique) continue;
return i+L;
}
return -1;
} This is simple function solves the problem and is fast to just call directly from the blueprint (see header image), so lets now take a moment to look at some Unit Testing:
// in a new file, AoC2022D05_Test.cpp
#include "Misc/AutomationTest.h"
#include "AoC22BPFunctionLibrary.h"
//
// The very simplest C++ Unit test that can be run by the UE Session Frontend / Automation tab
// See: https://docs.unrealengine.com/4.27/en-US/TestingAndOptimization/Automation/TechnicalGuide/
//
IMPLEMENT_SIMPLE_AUTOMATION_TEST(FAoC2022D05_Test, "AOC.2022.D05", EAutomationTestFlags::ApplicationContextMask | EAutomationTestFlags::ProductFilter)
bool FAoC2022D05_Test::RunTest(FString const& Parameters)
{
// PART 1
TestEqual(TEXT("bvwbjplbgvbhsrlpgdmjqwftvncz: first marker after character 5"),
UAoC22BPFunctionLibrary::FindStartOfPackerMarker(TEXT("bvwbjplbgvbhsrlpgdmjqwftvncz")), 5);
// (the next three test cases have been removed for brevity)
// PART 2
TestEqual(TEXT("mjqjpqmgbljsphdztnvjfqwrcgsmlb: first marker after character 19"),
UAoC22BPFunctionLibrary::FindStartOfPackerMarker(TEXT("mjqjpqmgbljsphdztnvjfqwrcgsmlb"), 14), 19);
// (the next four test cases have been removed for brevity)
// return TRUE if the test passes
// note: the test as a whole still fails if the "Test" macros failed
return true;
}
In Rider I can now right-click on the source file and Run Unit Test:

And this compiles and runs and I get results direct in the IDE:

If you are not fortunate enough to have access to a Rider license (you need the pro/ultimate edition for this tight Unreal integration), then the tests can be run from the Editor -> Session Front End -> Automation. If the Session Front End tab isn’t open by default (it was for me but this seems to be new in 5.1), you can find it under the Tools menu.
I will likely use this more over the remaining days, as the problems get harder. A TDD workflow is a great fit for Advent of Code.
