Advent Of Code Day 3
Day 3: Gear Ratios
https://adventofcode.com/2023/day/3
On day 3, we’re given an “engine schematic”:
467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..
For part 1, sum the numbers adjacent to a symbol (excluding dots).
Many possible options. Here’s one:
data←↑⊃⎕NGET'3'1
digits←data∊⎕D
dd←digits+({((5⊃,⍵)∊⎕D)∧(0<≢(,⍵)~' .0123456789')})⌺3 3⊢data
+/⍎¨(digits⊆⍤1 1⊢data)[⍸2∊¨digits⊆⍤1 1⊢dd]
Nothing too clever. For part 2, we’re asked to locate ‘gears’, defined as being two numbers (no more, no fewer) adjacent to the same symbol *
. This is a bit harder. Here’s an annotated solution, adapted from one written by Aaron Hsu:
part2 ← { ⍝ Based on a solution from Aaron Hsu
⍝ Id all *s by their ravel index
sh ← ⍴⍵
stars ← sh⍴(⍳×/sh)×,'*'=⍵
⍝ Fill each *'s 3×3 neighbourhood with its id.
catchment ← {⌈/⌈/⍵}⌺3 3⊢stars
⍝ Generate a mask showing the location of the numbers
digits ← ⍵∊⎕D
⍝ .. and use this to extract the numbers in ravel order.
numbers ← ⍎¨digits⊆⍥,⍵
⍝ We can use the digits mask to grab from the gear
⍝ catchment areas in the same way. We pick the max
⍝ as we don't care if several digits of the same number
⍝ may fall within the same catchment area.
gears ← ⌈/¨digits⊆⍥,catchment
⍝ In order to qualify, a gear must have exactly two numbers
⍝ in its catchment area
+/{2=≢⍵:×/numbers[⍵]⋄0}⌸gears
}
‘Tagging’ a Boolean mask with the corrsponding ravel index is something likely to be useful for other problems:
stars ← sh⍴(⍳×/sh)×,'*'=⍵
The problems are definitely harder this year, perhaps in an attempt to confuse LLMs.
Written on December 5, 2023