0

I'm learning a spread of programming languages in a class, and we're working on an APLX project at the moment. A restriction we have to work around is we cannot use If, For, While, etc. No loops or conditionals. I have to be able to take a plane of numbers, ranging 0-7, and replace each number 2 or greater into the depth of that number, and, ideally, change the 1's to 0's. For example:

0100230 => 0000560

I have no idea how I'm supposed to do the replacement with depth aspect, though the change from ones to zeros is quite simple. I'm able to produce the set of integers in a table and I understand how to replace specific values, but only with other specific values, not values that would have to be determined during the function. The depth should be the row depth, rather than the multi-dimensional depth.

For the record this is not the whole of the program, the program itself is a poker dealing and scoring program. This is a specific aspect of the scoring methodology that my professor recommended I use.

TOTALS„SCORE PHAND;TYPECOUNT;DEPTH;ISCOUNT;TEMPS;REPLACE
:If (½½PHAND) = 0
  PHAND„DEAL PHAND
:EndIf
TYPECOUNT„CHARS°.¹PHAND
DEPTH„2Þ(½TYPECOUNT)
REPLACE „ 2 3 4 5 6 7
ISCOUNT „ +/ TYPECOUNT

ISCOUNT „ ³ISCOUNT
((1=,ISCOUNT)/,ISCOUNT)„0
©((2=,ISCOUNT)/,ISCOUNT)„1
©TEMPS „ ISCOUNT
Œ„ISCOUNT
Œ„PHAND
Susannah Potts
  • 837
  • 1
  • 12
  • 32
  • What exactly do you mean by "into the depth of that number"? – Lobachevsky Mar 11 '15 at 06:40
  • Specifically I mean row depth. APLX is all new to me, I'm not entirely sure what the proper phrasing would be for it. I'm looking at it from the point of view of a C/C++/Python/Java programmer. Depth or index value would be my way of thinking about it. – Susannah Potts Mar 11 '15 at 18:39

2 Answers2

1

You may have missed the first lessons of your prof and it might help to look at at again to learn about vectors and how easy you can work with them - once you unlearned the ideas of other programming languages ;-)

Assume you have a vector A with numbers from 1 to 7: A←⍳7 A 1 2 3 4 5 6 7

Now, if you wanted to search for values > 3, you'd do:

      A>3
0 0 0 1 1 1 1

The result is a vector, too, and you can easily combine the two in lots of operations:

  • multiplication to only keep values > 0 and replace others with 0:

      A×A>3
    

    0 0 0 4 5 6 7

  • or add 500 to values >3

    A+500×A>3 1 2 3 504 505 506 507

  • or, find the indices of values > 3:

      (A>3)×⍳⍴A 
    

    0 0 0 4 5 6 7

Now, looking at your q again, the word 'depth' has a specific meaning in APL and I guess you meant something different. Do I understand correctly that you want to replace values > 2 with the ' indices' of these values? Well, with what I've shown before, this is easy:

A←0 1 0 0 2 3 0
      (A≥2)×⍳⍴A 
0 0 0 0 5 6 0

edit: looking at multi-dimensional arrays: let's look into this example:

      A←(⍳5)∘.×⍳10
      A
1  2  3  4  5  6  7  8  9 10
2  4  6  8 10 12 14 16 18 20
3  6  9 12 15 18 21 24 27 30
4  8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50

Now, which numbers are > 20 and < 30?

      z←(A>20)∧A<30 
      z 
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 1 1 1 0
0 0 0 0 0 1 1 0 0 0
0 0 0 0 1 0 0 0 0 0

Then, you can multiply the values with that boolean result to filter out only the ones satisfying the condition:

      A×z 
0 0 0 0  0  0  0  0  0 0
0 0 0 0  0  0  0  0  0 0
0 0 0 0  0  0 21 24 27 0
0 0 0 0  0 24 28  0  0 0
0 0 0 0 25  0  0  0  0 0

Or, perhaps you're interested in the column-index of the values?

      z×[2]⍳¯1↑⍴z
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 7 8 9 0
0 0 0 0 0 6 7 0 0 0
0 0 0 0 5 0 0 0 0 0

NB: this statement might not work in all APL-dialects. Here's another way to formulate this:

      z×((1↑⍴z)⍴0)∘.+⍳¯1↑⍴z
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 7 8 9 0
0 0 0 0 0 6 7 0 0 0
0 0 0 0 5 0 0 0 0 0

I hope this gives you some ideas to play with. In general, using booleans to manipulate arrays in mathematical operations is an extremely powerful idea in APL which will take you loooooong ways ;-)

Also, if you'd like to see more of the same, have a look at the FinnAPL Idioms - some useful shorties grown over the years ;-)

edit re. "maintaining untouched values": going back to example array A:

      A←(⍳5)∘.×⍳10
      A
1  2  3  4  5  6  7  8  9 10
2  4  6  8 10 12 14 16 18 20
3  6  9 12 15 18 21 24 27 30
4  8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50

Replacing values between 20 and 30 with the power 2 of these values, keeping all others unchanged:

      touch←(A>20)∧A<30 
      (touch×A*2)+A×~touch
  1  2  3  4   5   6   7   8   9 10
  2  4  6  8  10  12  14  16  18 20
  3  6  9 12  15  18 441 576 729 30
  4  8 12 16  20 576 784  32  36 40
  5 10 15 20 625  30  35  40  45 50

I hope you get the idea...

MBaas
  • 7,248
  • 6
  • 44
  • 61
  • That is what I am looking for, thank you very much. This pushes me in the right direction, but my professor never gave us an example of something like this. I am, frankly, having a very hard time unlearning the concepts necessary for C/C++, Java, Python, Assembly, etc. However, just to check, this does function correctly when the object passed is 3 dimensional yes? If not, if I reduced it to 2 dimensional, would it work then? – Susannah Potts Mar 08 '15 at 17:22
  • With a multi-dimensional array, the basic test `(A≥2)` would also work, but the `⍳⍴A`-part to determine the index would not work. I'll edit the original reply for multi-dim cases... – MBaas Mar 08 '15 at 17:35
  • This is perfect, thank you very much MBaas. I have been playing around with it and making headway. It's hard to get over loop addiction. – Susannah Potts Mar 09 '15 at 16:42
  • Thank you for the help MBaas, unfortunately, I'm not making much headway, the results I'm getting from that are not what I am hoping for. The issue that arises from these methods is that all the other values are being reduced to zero, but I need them to remain untouched so I may replace them later. This is, more or less, a poker scoring program but for license plates. I'll keep plugging away at it. – Susannah Potts Mar 09 '15 at 17:10
  • Maintaining values you're not interested in is not a big problem, I've added a small section to my reply, as formatting is easier there. But maybe you should think about the algorithm first , because the way you asked the question indicated that you wanted to replace irrelevant values with 0s! – MBaas Mar 09 '15 at 17:19
  • I'm going to add the code I have so far in my question, though it might take a little while as I'm unsure how to keep the unicode. At any rate, the idea is, I have N plates formed of (0-Z). For each pair in a plate, I need to replace it with the respective weight for the pair (1-36, where 0=1, 1=2, ... Z=36). If there is 3 of a kind, multiply that by 100, 4 of a kind: 10000, etc. So far, I can produce a multidimensional array that has the count of each character in each plate in order as rows. i.e. 0101323 becomes 2 2 0 2 0 0 0 0 0.... and so on. I've 0'd the 1's that show up already. – Susannah Potts Mar 09 '15 at 18:21
0

Or better: ask a new q, as otherwise this would truly take epic dimensions, whereas the idea of stackoverflow is more like "one issue - one question"...

MBaas
  • 7,248
  • 6
  • 44
  • 61
  • I'm just going to my professor's office hours tomorrow and hoping that he'll be able to walk me through it. Failing that, I'm cheating and using loops anyway. I'm not going to understand this language without a full course in it. – Susannah Potts Mar 09 '15 at 19:39
  • Good luck for that! :-) i'm out of office now, but will look up tutorial-link tomorrow, it's not as tough as it looks ;-) – MBaas Mar 09 '15 at 19:42
  • The wiki-entry for the APL-Tag has a some useful links for tutorials etc. which may help: http://stackoverflow.com/tags/apl/info – MBaas Mar 10 '15 at 06:34
  • 1
    It may be useful to first get the right answer using whatever means necessary, then to later reformulate (or optimise) the solution such that it becomes more APL-esque. (see Premature Optimisation) – Lobachevsky Mar 11 '15 at 06:56