ShareMyScreen/AdventOfCode/2023/03/GearRatios/rdm

From J Wiki
Jump to navigation Jump to search

day 3

 1sample=: {{)n
 2467..114..
 3...*......
 4..35..633.
 5......#...
 6617*......
 7.....+.58.
 8..592.....
 9......755.
10...$.*....
11.664.598..
12}}
13day3=: fread '2023-day3.txt'
14
15digits=:'0123456789'

Here, we had numbers and symbols, and we needed to sum the numbers which were touched (in any direction) by a symbol (any non-numeric character other than '.')

I plodded through this, breaking up the input into lines (and leaving the linefeed in each line for reasons I'll explain in a moment - but making sure to mark linefeeds as "not a symbol".

Next, I generated a bit matrix which represented the characters touched by each symbol, and I also located the start of each number in the initial argument. (This is why I left the linefeeds in place - so that each position in my matrices would match up with the same position in the raw argument.)

A running scan of the bits marking the number starts gives each number a unique id number (1, 2, 3, 4), .. let's dive into the code for a moment, with globals assigned to make it easy to inspect intermediate results:

17part1=: {{
18  chmat=: ];.2 y
19  symbol=: chmat e.  a.-.'.',digits,LF
20  touched=: ,+./(_1 0 1)|."0 2 +./(_1 0 1)|."0 1/ symbol
21  numeric=: ,chmat e. digits
22  segments=: }:0 1 E.0,numeric
23  keep=: <:}.~.0,touched#numeric*+/\segments
24  numbers=: segments ".@([-.-.)&digits;.1,chmat
25  +/keep{numbers
26}}
   part1 sample
4361
   ($symbol)$touched
0 0 1 1 1 0 0 0 0 0 0
0 0 1 1 1 0 0 0 0 0 0
0 0 1 1 1 1 1 1 0 0 0
0 0 1 1 1 1 1 1 0 0 0
0 0 1 1 1 1 1 1 0 0 0
0 0 1 1 1 1 1 0 0 0 0
0 0 0 0 1 1 1 0 0 0 0
0 0 1 1 1 1 1 0 0 0 0
0 0 1 1 1 1 1 0 0 0 0
0 0 1 1 1 1 1 0 0 0 0
   ($symbol)$numeric*+/\segments
1 1 1 0 0  2  2  2 0 0 0
0 0 0 0 0  0  0  0 0 0 0
0 0 3 3 0  0  4  4 4 0 0
0 0 0 0 0  0  0  0 0 0 0
5 5 5 0 0  0  0  0 0 0 0
0 0 0 0 0  0  0  6 6 0 0
0 0 7 7 7  0  0  0 0 0 0
0 0 0 0 0  0  8  8 8 0 0
0 0 0 0 0  0  0  0 0 0 0
0 9 9 9 0 10 10 10 0 0 0

As you can see, each number that is adjacent to a symbol has a non-zero id here in this intermediate result. The unique values here (after discarding zeros) correspond to indices into the list of represented numbers.


For part 2, I wanted the product of pairs of numbers which were adjacent to asterisks. Here, I brute forced it and paired the ids adjacent to every place in the matrix and then selected those which corresponded to asterisks.

28part2=: {{
29  sh=: $chmat=: ];.2 y
30  asterisk=: I.,chmat e. '*'
31  numeric=: chmat e. digits
32  segments=: sh$0 1 E.0,,numeric
33  numbers=: (,segments) ".@([-.-.)&digits;.1,chmat
34  ids=: sh$(,numeric)*+/\,segments
35  adjacent=: ~.@,each/_1 0 1|."0 2~.@,each/_1 0 1|."0 1/ids 
36  pairs=: <:>(#~ 2=#@>)asterisk{,adjacent -.each 0
37  +/*/|:pairs{numbers
38}}

It turns out that there were never more than 2 numbers next to an asterisk. At the very least, that means I could have eliminated the (#~ 2=#@>) from the result. It also probably would have made more sense to only locate ids adjacent to asterisks rather than everywhere.

day 2 day 4