(I've decided to drop links to previous day content -- it's not
interesting enough)

Puzzle page: https://adventofcode.com/2021/day/5

For day 5, we were asked to consider lines of "vents", described in
terms of the coordinates of their endpoints. The sample data looked
like this:

sample=: {{)n
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2
}}

Those lines almost look like executable J. If I replaced the -> with
,: though, that would not quite work because I would need parenthesis.
But if I also replace the commas with spaces, J could handle the rest.

So:
use=: {{
  ".;._2 rplc&(',';' ';'->';',:') y
}}

This gives me a rank three array. leading dimension represents vents,
middle dimension distinguishes starting point from ending point, final
dimension distinguishes x from y coordinates.

For the first part of the puzzle, we only consider vertical and
horizontal lines of vents.  So either the x or the y coordinate would
need to be the same.

And, we are counting coordinate pairs which have vents from more than one line.

So, the first thing we would need is a mechanism for determining all
the coordinates touched by a vent. For that, I used

   thru=: [ ~.@, <. + i.@(+*)@-~

Example use:
   1 thru 3
1 2 3
   3 thru 1
3 2 1
   3 thru 3
3

(This routine also turns out to be useful in some later advent of code puzzles.)

There's one difficulty here, which is that I want to use thru on both
x and y, and I want to combine pairs, but I want scalar extension to
work. For example, if there's only a single x value and there's five y
values, I want that same x value for every y value. To achieve this, I
used ".@": on each of the results of thru (losing the unnecessary 1
dimension, where it is present) and then combined x and y using ,.

Once I had my coordinate pairs for each vent, I merge them into a big
list, use #/.~ to count how many occurrences each unique pair had and
count how many had more than one instance:

a5=:{{
  b=. +./"1 =/"2 data=. use y
  +/1 < #/.~ ;,.each/"1 <@".@":@thru/"1@|:"2 b # data
}}

For the second part, I needed to do the same thing, including diagonal
vent lines. Since those diagonal lines are all 45 degree lines, the
mechanism I used would already work, if I do not discard those vent
lines:

b5=:{{
  +/1 < #/.~ ;,.each/"1 <@".@":@thru/"1@|:"2 use y
}}

We're still warming up here, but hopefully this isn't too boring.

FYI,

-- 
Raul
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to