When I first started APL in August 2012, I was pointed in the direction of the annual International APL Problem Solving Competition run by Dyalog. I used it as method to practice what I had learnt. While I looked at the problems I saw one based on the poker game Texas hold ’em. It revolved around calculating the value of a hand with a series of tasks about calculating stats and determining best hands in different circumstances. I decided to take a step back and look at dealing with a deck of cards.
The first thing to do was initialise a deck of cards. So I set the card values and the suits:
CardValues←'2' '3' '4' '5' '6' '7' '8' '9' '10' 'J' 'Q' 'K' 'A' Suits←'H' 'D' 'S' 'C'
I then needed to combine the two in a way that would give me a full suit of each (a full set of card values for each suit). Using the catenate function (
,) we can join arrays together (e.g
ab). When used with outer product (
∘.) like this
∘., it will catenate each possible combination of two vectors.
The comma symbol, when used monadically (meaning with only the right argument) means ravel, which flattens complex structures into a vector (i.e if
table is a 2 by 2 matrix of the numbers 1-4, then using ravel on it like this
,table gives us
1 2 3 4 a flattened version of
Putting this all together gives us:
Deck is then a flat vector of 52 items, each of which is a different card. Now we have all the available cards from a standard 52 card deck. I am also using reshape (
⍴) to display the contents of the variable
Deck in a 13 row by 4 column matrix to make it more readable.
13 4⍴Deck 2H 2D 2S 2C 3H 3D 3S 3C 4H 4D 4S 4C 5H 5D 5S 5C 6H 6D 6S 6C 7H 7D 7S 7C 8H 8D 8S 8C 9H 9D 9S 9C 10H 10D 10S 10C JH JD JS JC QH QD QS QC KH KD KS KC AH AD AS AC
The rho (
⍴) symbol when used dyadically (meaning with two arguments; a left and a right argument) as above will reshape an array (right argument) by the dimensions (left argument).
To then deal a hand of cards from the
Deck I used the query symbol (
?) which when used dyadically means deal. Deal picks a random selection of numbers from 1 to the number specified as the right argument (i.e
1?10 returns 1 random number between 1 and 10). Using the
Deal function against the length of the
⍴Deck this returns the shape/length of the right argument when used monadically) then using the result to index (
c) into the
Deck and assign (
← assign right argument into left argument) the result into the variable
We then want to remove the cards we have already dealt from
Deck. The without function (
~) removes the right argument from the left (e.g.
'adf'). We can use this function as an operand in a modified assignment to remove the
Hand from the
I wrote this code when I had only been doing APL for a month or so. It was a very interesting and educational task to undertake and I learnt a lot of new techniques. Is there anything that I could have done better? Are there any interesting alternatives to what I wrote?
If you would like to find out more about the competition or the problem I have mentioned (the 2012 competition under previous years near the bottom of the page) see Dyalog’s International Problem Solving Competition.