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

  • ystael@beehaw.org
    link
    fedilink
    arrow-up
    2
    ·
    15 days 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