I started to work the event, using it to learn J.  Of course none of my code is as elegant as that already shared in the forum by you and others...

On 12/25/21 7:08 PM, Raul Miller wrote:
(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,

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

Reply via email to