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 6 is about rearranging the input to be able to complete some simple arithmetic equations. 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 grid showing columns of numbers followed by the operation that needs to be applied to them. The aim of the puzzle is to determine, for your own dataset, the total sum of all the equations.
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
| eval _raw="123 328 51 64
45 64 387 23
6 98 215 314
* + * + "The next step is to break the data up into separate events,
| rex max_match=0 "(?<line>[^\r\n]+)"
| mvexpand lineEach line holds a row in a column of numbers followed by a line with the mathematical operation that needs to be applied to all the numbers in the column; this is either plus (+) or multiply (*). Each column is separated by one or more white spaces. So, extract the groups of non-white spaces using the rex command.
| rex max_match=0 field=line "(?<value>\S+)"
| fields - _time _raw line _mkv_childPart One is calculating the value of the columns based on the operator found at the bottom of the column. To make it easier, reverse the events to get the operator at the top of the column.
| reverseGive each event a name
| streamstats count as operand
| eval operand="operand_".operandTranspose to get a field for the operator and each operand of the equations.
| transpose 0 header_field=operandRename the first field as operator since this contains the operators required for each equation.
| rename operand_1 as operatorRename the second field as total since this contains the running total for each equation.
| rename operand_2 as totalCreate a list of indexes for the multi-value fields.
| eval list=mvrange(0, mvcount(operator))For the remaining operands, process each equation
| foreach operand_*
[
| foreach mode=multivalue list
[Update the (running) total for each equation based on the corresponding operator.
| eval result=if(mvindex(operator, <<ITEM>>)="+", tonumber(mvindex(total, <<ITEM>>)) + tonumber(mvindex(<<FIELD>>, <<ITEM>>)), tonumber(mvindex(total, <<ITEM>>)) * tonumber(mvindex(<<FIELD>>, <<ITEM>>))),
new_total=mvappend(if(<<ITEM>>=0, null(), mvindex(total, 0, <<ITEM>>-1)), result, mvindex(total, <<ITEM>>+1, -1)),
total=new_totalNow, simply sum the totals from all the equations.
| stats sum(total) as totalThe second part of the puzzle requires that again we determine, for your own dataset, the total sum of all the equations,, but, this time the numbers should be considered vertically.
Starting in the same manner as Part One, extract each line from the input
| rex max_match=0 "(?<line>[^\r\n]+)"
| mvexpand lineGive each row an id and extract each character from the line.
| streamstats count as row
| rex max_match=0 field=line "(?<char>.)"Expand the characters into columns and give each column an id.
| mvexpand char
| streamstats count as column by row global=fSince we need to process the columns in the correct order, adjust the id so that the lexicographical sort order is also the numeric order. (Since there are fewer than 10,000 columns in my dataset, I have simply added 10,000 to the count.)
| eval column=10000+columnUse the chart command to list the characters by column over a constant value (I have used _time from the original makeresults - if you have lost this, re-instate it or set another field to a constant value).
| chart list(char) as char over _time by column limit=0 useother=fNow, we can convert back to a table with the untable command. Note the use of underscore (_) for the first field name - this effectively hides the constant field that the chart command used.
| untable _ field valueUse our old friend rex to extract the operator and digits from the list of characters in the value field.
| rex field=value "(?<operator>\*|\+)"
| rex max_match=0 field=value "(?<digit>\d)"Combine the digits into a number for the column.
| eval number=tonumber(mvjoin(digit,""))Using streamstats to count the (non-null) operators, we can get an id for each equation.
| streamstats count(operator) as equationUse stats to gather numbers (operands) and operator for each equation.
| stats list(number) as operands values(operator) as operator by equation
| fields - equationInitialise a running total for each equation depending on the operator being used (multiplying by one or adding zero does not change the result).
| eval total=if(operator="*", 1, 0)For each of the operands, combine it with the running total using the appropriate operator.
| foreach mode=multivalue operands
[
| eval total=if(operator="*", total*<<ITEM>>, total+<<ITEM>>)
]Now, simply sum the totals from all the equations.
| stats sum(total) as totalThere are many ways to solve this puzzle, and, in the end, I settled on slightly different approaches for Part One and Part Two. Part One used nested foreach loops to iterate over the operands updating the multi-value field of totals for each equation, all within a single event. Part Two separated each equation to its own event before iterating over the operands to determine the result for each equation.
Have questions or thoughts? Comment on this article or in Slack #puzzles channel. Whichever you prefer.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.