Day 2

Now that I’m a little more comfortable with April, I jumped straight into APL. This problem maps quite well into APL, so long as we think in arrays of course! We just need to encode the rock-paper-scissors game into a table:

   X Y Z
 A 3 6 0
 B 0 3 6
 C 6 0 3

Here’s the full APL solution, which I’ll describe below. 1

scores  3 3  3 6 0 0 3 6 6 0 3
lefts  'ABC'
rights  'XYZ'
score  {
l  lefts  ( ⍵)
r  rights  (3  ⍵)
r + l r  scores
ans1  +/ score ¨ in
  1. We define the lookup table as shown above, using reshape () to turn the 1D array into a 3x3 2D array, since you can’t directly enter higher-rank arrays.
  2. We pass the input into APL as a vector of strings, and use first/pick () to grab the first and third characters, then map the characters to indices (with “index of” ) to lookup the outcome/points in the table with index (). We then add the index of our play, which is convenientally also its value for the total score.
  3. Since we have to do this for every line we wrap it in a function (in APL functions are blocks delimited with curly braces that can be assigned to a variable. The right argument is in and the left argument, if there is one, is in ).
  4. We then call the function for every string (line) in the input array using each (¨), and sum using reduce (+/).

I’m not sure how idiomatic my APL is, probably a bit verbose and with excessive parens. I try to use variables and parens to make the logic a bit clearer.

Part 2 is similar, but instead of mapping the second column to an index, we map it to a desired outcome (score), then look up the index for the outcome in the row for the opponent’s play.

scores  3 3  3 6 0 0 3 6 6 0 3
lefts  'ABC'
rights  'X..Y..Z'
score  {
l  lefts  ( ⍵)            ⍝ opponent's play
p  (rights  (3  ⍵)) - 1   ⍝ how many points we need
p + (l  scores)  p         ⍝ find the index (value) for our play, plus points we need
ans2  +/ score ¨ in

The dots in rights are just placeholder characters to get the outcome aligned with its value (plus one, which we’ll subtract after). Note that we only pass one value to index (), which then returns the whole row.

  1. I won’t bother posting the CL any more unless there’s critical or interesting logic in there. ↩︎

Next: Advent of Code 2022 part 3
#adventofcode (23)
#apl (5)
#baking (1)
#biggreenegg (9)
#chia (5)
#data-visualization (8)
#development (46)
#devops (4)
#docker (1)
#electronics (7)
#engineering (9)
#food (11)
#golang (1)
#home-improvement (3)
#julia (17)
#keto (1)
#keyboards (4)
#lisp (8)
#meta (1)
#monitoring (10)
#photos (13)
#racket (1)
#recipes (6)
#rust (1)
#woodworking (12)