Counting cards in APL

Sam GutsellAPLLeave a Comment

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 Task

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 ‘a’,’b’ returns 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 table).

Putting this all together gives us:


Deck←,CardValues∘.,Suits

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 (⍴Deck this returns the shape/length of the right argument when used monadically) then using the result to index ([x] i.e 'abcdef'[3] returns c) into the Deck and assign ( assign right argument into left argument) the result into the variable Hand.


Hand←Deck[2?⍴Deck]

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. 'abcdef'~'bce' returns 'adf'). We can use this function as an operand in a modified assignment to remove the Hand from the Deck.


Deck~←Hand

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.