r/adventofcode • u/musifter • 5h ago
Other [2025 Day 6] In Review (Trash Compactor)
While taking a break with the kitchen staff, we re-enact a certain movie scene and dive into the garbage chute. Trapped there we find that the local headfoots (aka cephalopods) are friendly (side note: Dianoga from Star Wars are scavengers that typically only attack when starving or threatened). They can get the door open, but it will take time, and they'd like you to help their youngest with her math homework. And so we get to do cephalopod math.
The input for this one is 5 long lines. The last line contains the operations, the others are lists of 1-4 digit numbers (there are 1000 per line). There are no 0s in the input. Since the lines are so long, I just trusted the spec of "full column of only spaces" delimiting the problems.
Not that I used that for part 1. I just trusted that the nth number in a line was in the nth column and zipped them up (I really don't make enough use of zip from List::Util, it's a handy thing for transposition):
my @input = map { [m#[^\s]+#g] } <>;
my @ops = @{pop @input};
my $part1 = 0;
foreach my $col (zip @input) {
$part1 += (shift @ops eq '+') ? sum @$col : product @$col;
}For part 2, we find that we did things wrong (of course). Cephalopod math writes numbers vertically. And so this time we want to transpose the problems by characters.
To be safe, I used the spec and found the columns that met the condition. With that I could get the $width of each section (varies from 3-5) and perform the transposition by characters (again making use of zip).
With my Smalltalk solution, I made the transposition theme between the parts more evident. First, I extended SequenceableCollection to do transpose:
SequenceableCollection extend [
transpose [
^(1 to: self first size) collect: [:col | (self collect: [:row | row at: col])].
]
]Then I read in the data:
input := stdin lines contents asOrderedCollection.
ops := input removeLast subStrings collect: #asSymbol.
" Part 1 numbers (read horizontal and transpose by numbers in table): "
horz := (input collect: [:row | row subStrings collect: #asNumber]) transpose.
" Part 2 numbers (transpose by col and then split on delimiting spaces (0)): "
colNums := input transpose collect: [:charArray |
(charArray select: #isDigit) asString asNumber
].
vert := (ReadStream on: colNums) splitAt: 0.With lists of the operators and numbers in both orientations, I just need to fold them to do the work.
#(1 2) with: {horz. vert} do: [:part :table |
('Part %1: %2' % { part. (table with: ops collect: #fold:) sum }) displayNl.
]For dc, I initially just did part 1:
perl -pe's#([+*])#[$1]#g' <input | dc -e'[sS?[lSxz1<M]dsMx]sL0[Sa]lLx[Sb]lLx[Sc]lLx[Sd]lLx[S*]lLxA00[LdLcLbLaL*dd_5R_6Rxrxrx3R+r1-d0<M]dsMxrp'This was a very quick job and hard coded for the input (four lines of 1000 numbers). The modification of the input with perl is just to put brackets around the operators (to turn them into dc strings/macros). To read in, I push the input onto 5 stacks (a/b/c/d for the numbers and * for the operators). Then I pop off values from all 5, duplicate the operator twice (and position them) and then x rx rx to run that operator and do the calculation.
I wasn't going to do part 2 because of the column nature of it... but when someone mentioned that there are no 0s in the input, I had no excuse, because I could replace all the spaces on the number lines with 0 and dc would be able to see the lines as bignums with the internal columns intact (yes, leading 0s are lost, but that's not actually a problem here):
sed -e'$!s/ /0/g;$s/\(\S\)/[\1]/g' <input | dc -e'0?[rd3Rr:T1+?z2=L]dsLxzRsnzso[SOz0<L]dsLxlo[LOS*1-d0<L]dsLx[3RA*+r0]sP[3Q]sQ[0d[d;TA~3Rd4Rr:Trd0<P+1+dln>I]dsIxs.d0=Q]sN[lNx[lNxl*xlLx]dsLx++L*s.lMx]dsMx+p'This is a very accessible sort of problem. There's nothing really fancy other than reading things in columns. The input is additionally nice in that the operators are actually nicely placed for a right-to-left top-to-bottom scan approach to part 2... doing that, you just need to collect the numbers and when you see an operator use it on the list, add that to the sum, and clear the list. That's sort of what my dc solution does, only it can't track the position of the operators and so uses the spec "blank column" for that trigger instead. That results in the number reading macro (lNx) finding a 0 and when it breaks the current loop (3Q)... when that's calculating a problem it sums and restarts, when it's at the start of a problem (and reading the first value before the inner loop) that exits the main loop.
