VII: The Programmatic Side of Mathematica: Dealing Cards

You might recall in our last post, we had a way of declaring a deck of cards:

deck = Flatten[Outer[List, {s, h, c, d},
       Join[Range[2, 10], {J, Q, K, A}]], 1]

… but alas, no way yet of dealing random cards. And this was because we said there was no way of actually shuffling the deck. Mathematica would likely provide a way, but it is probably better to declare a function that randomly deals out the cards, while removing the cards it deals from the deck. To see this more easily, let’s declare a small set whose results are easier to see:

m= {2,4, 6, 8, 12, 78, 114}

We need to declare a function that chooses a random element from the list:

Random[Integer, {1, Length[m]}]

The number 3 returned is not from the list, but random integer between 1 and the list length. That is, the third element in the list, or the number 6. This can still be useful, however:

removeRand[lis_]:=Delete[lis, Random[Integer,{1, Length[lis]}]]

We can pass this random element number into a function which deletes the number at the random position from the list, as shown above. But don’t we want to deal that card also? There is not really any way I can think of that can both delete and return an element, but there is a way we may use set theory. If I delete an element n from set A, then A’s complement (or “not A”) becomes the deleted element n.

Complement[m, removeRand[m]]

On the same call, m is the same copy with all the original elements. So, in this call to Complement[], an element is randomly removed from set m. This new set, without the “12”, is now compared against m to find the new set’s complement, the number that was removed, and it is displayed. removeRand[] evidently returned a “5”, which is the number 12, the 5th element in m. A new subset of m {2,4,6,8,78,114} is compared against m to determine the complement, and 12 is returned. Throughout this operation, m never really gets modified.

When we deal cards from a deck, we want to deal several cards in one hand. In rummy, that can consist of 7 cards, depending on how many people are playing (Wikipedia says up to 13 cards for two-handed rummy). So, let’s declare a function which will help us deal cards:

hand[n_]:=Complement[deck, Nest[removeRand, deck,n]]

What Nest[] does is remove n cards recursively from a set called “deck”, the set we originally declared in today’s article. The complement between “deck” and “deck” with 7 rummy cards removed, is the rummy hand.


With a pair of aces at the start, it’s not a bad hand, although your opponent might do better.