this post was submitted on 11 Dec 2024
13 points (93.3% liked)

Advent Of Code

1012 readers
1 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 2 years ago
MODERATORS
 

Day 11: Plutonian Pebbles

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

you are viewing a single comment's thread
view the rest of the comments
[โ€“] ystael@beehaw.org 2 points 2 months ago

J

If one line of code needs five lines of comment, I'm not sure how much of an improvement the "expressive power" is! But I learned how to use J's group-by operator (/. or /..) and a trick with evoke gerund (`:0"1) to transform columns of a matrix separately. It might have been simpler to transpose and apply to rows.

data_file_name =: '11.data'
data =: ". > cutopen fread data_file_name
NB. split splits an even digit positive integer into left digits and right digits
split =: ; @: ((10 & #.) &.>) @: (({.~ ; }.~) (-: @: #)) @: (10 & #.^:_1)
NB. step consumes a single number and yields the boxed count-matrix of acting on that number
step =: monad define
   if. y = 0 do. < 1 1
   elseif. 2 | <. 10 ^. y do. < (split y) ,. 1 1
   else. < (y * 2024), 1 end.
)
NB. reduce_count_matrix consumes an unboxed count-matrix of shape n 2, left column being
NB. the item and right being the count of that item, and reduces it so that each item
NB. appears once and the counts are summed; it does not sort the items. Result is unboxed.
NB. Read the vocabulary page for /.. to understand the grouped matrix ;/.. builds; the
NB. gerund evoke `:0"1 then sums under boxing in the right coordinate of each row.
reduce_count_matrix =: > @: (({. ` ((+/&.>) @: {:)) `:0"1) @: ({. ;/.. {:) @: |:
initial_count_matrix =: reduce_count_matrix data ,. (# data) $ 1
NB. iterate consumes a count matrix and yields the result of stepping once across that
NB. count matrix. There's a lot going on here. On rows (item, count) of the incoming count
NB. matrix, (step @: {.) yields the (boxed count matrix) result of step item;
NB. (< @: (1&,) @: {:) yields <(1, count); then *"1&.> multiplies those at rank 1 under
NB. boxing. Finally raze and reduce.
iterate =: reduce_count_matrix @: ; @: (((step @: {.) (*"1&.>) (< @: (1&,) @: {:))"1)
count_pebbles =: +/ @: ({:"1)
result1 =: count_pebbles iterate^:25 initial_count_matrix
result2 =: count_pebbles iterate^:75 initial_count_matrix