Advent Of Code Day 3

Day 3: Gear Ratios

On day 3, we’re given an “engine schematic”:


For part 1, sum the numbers adjacent to a symbol (excluding dots).

Many possible options. Here’s one:

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

‘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