It’s Christmas, and after a long day of food and wine and opening gifts with my family, I have settled down to todays puzzle: Number parsing in a weird base. Day 25 is in AoC tradition, a bit easier than the previous weeks challenges. My solution is mostly C++ with a little Blueprint thrown in.
Lets start with the parse. You will have seen me do this in base 10 for previous puzzles such as Advent of Code in Unreal Engine Day 22 and Advent of Code in Unreal Engine Day 21. Converting these to the puzzles “base 5 but offset -2” is changing the multiplier and mapping = and – to their negative integer values. The only “gotcha”, it needs to be a 64 bit int, or some of the puzzle input will overflow:
int64 UAoC22BPFunctionLibrary::ParseSnafu(const FString& String) { int64 Total = 0; for (int i=0;i!=String.Len();++i) { Total = Total * 5; int n = 0; auto c = String[i]; switch (c) { case '=': n=-2; break; case '-': n=-1; break; default: n=c-'0'; break; } Total += n; } return Total; }
I was confident, but I used the problem description example for some unit tests anyway:
TestEqual( TEXT("1=-0-2 -> 1747"), UAoC22BPFunctionLibrary::ParseSnafu(TEXT("1=-0-2")), 1747ll); TestEqual( TEXT("12111 -> 906"), UAoC22BPFunctionLibrary::ParseSnafu(TEXT("12111")), 906ll); TestEqual( TEXT("2=0= -> 198"), UAoC22BPFunctionLibrary::ParseSnafu(TEXT("2=0=")), 198ll); TestEqual( TEXT("21 -> 11"), UAoC22BPFunctionLibrary::ParseSnafu(TEXT("21")), 11ll); TestEqual( TEXT("2=01 -> 201"), UAoC22BPFunctionLibrary::ParseSnafu(TEXT("2=01")), 201ll);
Going the other way, I was less confident, but figured it would probably be like a normal atoi implementation, but where the reminder was 3 or 4, I’d need to use the – or = and add 5. For 3=5-2, for 4=5-1. A bit like carrying the overflow when doing long form addition as a kid.
I added the unit tests:
TestEqual( TEXT("0"), UAoC22BPFunctionLibrary::MakeSnafu(0), "0" ); TestEqual( TEXT("1"), UAoC22BPFunctionLibrary::MakeSnafu(1), "1" ); TestEqual( TEXT("2"), UAoC22BPFunctionLibrary::MakeSnafu(2), "2" ); TestEqual( TEXT("3"), UAoC22BPFunctionLibrary::MakeSnafu(3), "1=" ); TestEqual( TEXT("4"), UAoC22BPFunctionLibrary::MakeSnafu(4), "1-" ); TestEqual( TEXT("5"), UAoC22BPFunctionLibrary::MakeSnafu(5), "10" );
Then implement my MakeSnafu, it ends up looking like this:
FString UAoC22BPFunctionLibrary::MakeSnafu(int64 V) { FString Result; do { int X = V%5; V = V/5; switch (X) { case 3: Result.AppendChar(TCHAR('=')); V++; break; case 4: Result.AppendChar(TCHAR('-')); V++; break; default: Result.AppendChar(TCHAR('0')+X); break; } }while(V); Result.ReverseString(); return Result; }
Once the tests passed, I was able to stitch it all together with Blueprint:
So what now?
I have 8 stars missing. Some because Part 2 defeated me, some because I didn’t have time on that day. Time permitting I’ll be exploring the skipped days, then I’ll go back to the too-hard puzzles to finish things off.