ShareMyScreen/AdventOfCode/2022/01/CalorieCounting JP

From J Wiki
Jump to navigation Jump to search

The Problem >>

I generally develop my J solutions to Advent of Code on my phone using JAndroid, loading files I created with Vim in a terminal emulator. This causes my solutions to tend to be dense/concise, but I'll try my best to explain.

For any date I assume the input to be in a file dd.txt where dd is the 2-digit day number, i.e. for this day 01.txt.

i1=: 0,~ , 0&".;._2 freads '01.txt'
part1=: [: >./ +/;._2
part2=: [: (3 +/@{. \:~) +/;._2
(part1;part2) i1 NB. yields solution.

Input parsing

I noticed there are no 0 weights in my input, so I decided to use 0 as separator for the Elves backpacks. The first line reads and parses the input. I'll explain from the right to the left, as that is the "natural" direction data flows in J.

freads is defined in the Standard library, stdlb and reads a file as a string from a given filename.

0&": converts strings to numbers, with 0 being the default number if the string is an invalid number.

In u ;. _2 the Cut conjunction (;.) applies function u (in this case 0&":) to chunks defined by the last element of the array given (omitting that element as it goes), in this case the final line feed in the input file. That is, each line is converted to a number, and 0's appear where there are no numbers.

So far, the Shape of the result is N 1, where N is the number of numbers in our list. The rightmost comma removes this trailing 1 dimension, so we have a simple list to work with.

As the number of items in each backpack is variable, cut is the natural way to implement the solutions for part 1 and 2. As we used 0&". before empty lines, backpacks are already separated by 0's. To also have a 0 at the end, allowing to use ;._2 later, a 0 is appended, for convenience written as 0,~ . Alternatively, I could have added an extra LF just after the freads.

Part 1

The part1 verb is a capped fork, i.e. ([: g h) y is executed equivalently to g@:h y, or g(h(y)) in traditional mathematic notation. As h would require parentheses, I find a capped fork cleaner here. +/;._2 applies +/, i.e. sum, to each backpack, delimited by the 0 we appended to the input above. >./ takes the maximum of all the resulting backpack sums, to complete the solution to part 1.

Part 2

Skipping over the capped fork and backpack summing, (3 +/@{. \:~) is again a fork, with a noun as left tine, which is used as if it were the result of a verb. The right tine, \:~ is the common idiom for sorting an array in descending order (notice the direction of the backslash in \: as a mnemonic). The middle tine +/@{. is sum after take, i.e. in this case the 3 (from the left) of the largest (sorted up from the right) are taken (by {.) and summed.