# Advent Of Code Day 3

## Day 3: Gear Ratios

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