How to manipulate multiple nested arrays in Dyalog APL?

330 views Asked by At

I have been given matrices filled with alphanumerical values excluding lower case letters like so:

XX11X1X
XX88X8X
Y000YYY
ZZZZ789
ABABABC

and have been tasked with counting the repetitions in each row and then tallying up a score depending on the ranking of the character being repeated. I used {⍺ (≢⍵)}⌸¨ ↓ m to help me. For the example above I would get something like this:

X 4  X 4  Y 4  Z 4  A 3 
1 3  8 3  0 3  7 1  B 3 
               8 1  C 1 
               9 1     

This is great but now I need to do a function that would be able to multiply the numbers with each letter. I can access the first matrix with but then I am completely lost on how to access the other ones. I can simply write ⊃w[2] and ⊃w[3] and so forth but I need a way to change every matrix at the same time in one function. For this example, the array of the ranking is as follow: ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210 so for the first array XX11X1X which corresponds to:

X 4
1 3

So the X is 3rd in the array so it corresponds to a 3 and 1 is 35th so it's a 35. The final scoring would be something like (3×104)+(35×103). My biggest problem is not necessarily the scoring part but being able to access each matrix individually in one function. So for this nested array:

 X 4  X 4  Y 4  Z 4  A 3 
 1 3  8 3  0 3  7 1  B 3 
                8 1  C 1 
                9 1      

if I do arr[1] it gives me the scalar

 X 4
 1 3

and ⍴ arr[1] gives me nothing confirming it so I can do ⊃arr[1] to get the matrix itself and have access to each column individually. This is where I'm stuck. I'm trying to write a function to be able to do the math for each matrix and then saving those results to an array. I can easily do the math for the first matrix but I can't do it for all of them. I might have made a mistake by making using {⍺ (≢⍵)}⌸¨ ↓ m to get those matrices. Thanks.

1

There are 1 answers

0
Adám On BEST ANSWER

Using your example arrangement:

      ⎕ ← arranged ← ⌽ ⎕D , ⎕A
ZYXWVUTSRQPONMLKJIHGFEDCBA9876543210

So now, we can get the index values:

      1 ⌷ m
XX11X1X
      ∪ 1 ⌷ m
X1
      arranged ⍳ ∪ 1 ⌷ m
3 35

While you could compute the intermediary step first, it is much simpler to include most of the final formula in in Key's operand:

      { ( arranged ⍳ ⍺ ) × 10 * ≢⍵ }⌸¨ ↓m
┌───────────┬───────────┬───────────┬─────────────────┬───────────────┐
│30000 35000│30000 28000│20000 36000│10000 290 280 270│26000 25000 240│
└───────────┴───────────┴───────────┴─────────────────┴───────────────┘

Now we just need to sum each:

      +/¨ { ( arranged ⍳ ⍺ ) × 10 * ≢⍵ }⌸¨ ↓m
65000 58000 56000 10840 51240

In fact, we can combine the summation with the application of Key to avoid a double loop:

      { +/ { ( arranged ⍳ ⍺ ) × 10 * ≢⍵ }⌸ ⍵}¨ ↓m
65000 58000 56000 10840 51240

For completeness, here is a way to use the intermediary result. Let's start by working on just the first matrix (you can get the second one with 2⊃ instead of ― for details, see Problems when trying to use arrays in APL. What have I missed?):

      ⊃{⍺ (≢⍵)}⌸¨ ↓m
X 4
1 3

We can insert a function between the left column elements and the right column elements with reduction:

      {⍺ 'foo' ⍵}/ ⊃{⍺ (≢⍵)}⌸¨ ↓m
┌─────────┬─────────┐
│┌─┬───┬─┐│┌─┬───┬─┐│
││X│foo│4│││1│foo│3││
│└─┴───┴─┘│└─┴───┴─┘│
└─────────┴─────────┘

So now we simply have to modify the placeholder function with one that looks up the left argument in the arranged items, and multiplies by ten to the power of the right argument:

      { ( arranged ⍳ ⍺ ) × 10 * ⍵ }/ ⊃{⍺ (≢⍵)}⌸¨ ↓m
30000 35000

Instead of applying this to only the first matrix, we apply it to each matrix:

      { ( arranged ⍳ ⍺ ) × 10 * ⍵ }/¨ {⍺ (≢⍵)}⌸¨ ↓m
┌───────────┬───────────┬───────────┬─────────────────┬───────────────┐
│30000 35000│30000 28000│20000 36000│10000 290 280 270│26000 25000 240│
└───────────┴───────────┴───────────┴─────────────────┴───────────────┘

Now we just need to sum each:

      +/¨ { ( arranged ⍳ ⍺ ) × 10 * ⍵ }/¨ {⍺ (≢⍵)}⌸¨ ↓m
65000 58000 56000 10840 51240

However, this is a much more circuitous approach, and is only provided here for reference.