In order to participate in these challenges, you will need to register with the Advent of Code site, so that you can retrieve your own datasets for the puzzles. When you get an answer, you will need to submit it to the Advent of Code site to determine whether the answer is correct. I have already completed the 2025 set using python, so I will know when my SPL generates the correct result.
Each day's puzzle is split into two parts; part one is usually easier than part two, and you cannot normally reach part two until you have successfully completed part one. Day 3 is about finding the largest number from sequences of digits without changing the order of the digits. Please visit the website for full details of the puzzle.
This article contains spoilers!
In fact, the whole article is a spoiler as it contains solutions to the puzzle. If you are trying to solve the puzzle yourself and just want some pointers to get you started, stop reading when you have enough, and return if you get stuck again, or just want to compare your solution to mine!
As with all the Advent of Code puzzles, the description of the problem is aided by some example input; in this case, the input is sequences of digits. The aim of the puzzle is to determine, for your own dataset, the largest 2-digit number formed by digits in the sequence without changing the order of the digits.
The first thing to do is initialise your data. One way to do this is to save it to a csv file and use inputlookup to load it. Alternative, you could just use makeresults (as I have done here), and set a field to the data:
| makeresults
| fields - _time
| eval _raw="987654321111111
811111111111119
234234234234278
818181911112111"
The next step is to break the data up into separate events,
| rex max_match=0 "(?<batteries>\S+)"
| table batteries
| mvexpand batteries
Each digit needs to be processed separately, so split the sequence into a multi-value field and prepare an empty string for the result.
| eval new_batteries=split(batteries,"")
| eval result=""
Part One is looking for a 2 digit number, so iterate over the sequence of remaining digits twice.
| eval digits=2
| foreach 0 1
[
For each iteration, we need to find the highest digit, whilst leaving room in the string for the remaining iterations. Firstly, determine how much of the current sequence to search.
| eval count=mvcount(new_batteries)-digits+<<FIELD>>
| eval test_batteries=mvindex(new_batteries,0,count)
Search the current string for the first match of the digits in descending order.
| eval high_index=coalesce(mvfind(test_batteries,"9"),mvfind(test_batteries,"8"),mvfind(test_batteries,"7"),mvfind(test_batteries,"6"),mvfind(test_batteries,"5"),mvfind(test_batteries,"4"),mvfind(test_batteries,"3"),mvfind(test_batteries,"2"),mvfind(test_batteries,"1"))
Since mvfind() returns null() if there is no match, coalesce() is used to get the index of the highest digit. Concatenate the highest digit to the result so far.
| eval result=result.mvindex(new_batteries,high_index)
Reduce the list of digits to be searched in the next iteration, starting after the digit just removed, until the end of the list.
| eval new_batteries=mvindex(new_batteries,high_index+1,-1)
]
Now, simply sum the resulting numbers.
| stats sum(result) as total
Part Two is looking for a 12 digit number, so iterate over the sequence of remaining digits twelve times.
Using the same approach as for Part One, this time the number of digits in the result is 12, so we need to iterate the process twelve times.
| eval digits=12
| foreach 0 1 2 3 4 5 6 7 8 9 10 11
[
Sometimes, part two is simply just a larger version of part one, so it is important to have an efficient process.
Have questions or thoughts? Comment on this article or in Slack #puzzles channel. Whichever you prefer.
Never miss a new post. Check out this short guide on how to subscribe to the blog and get updates.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.