## The 2008 Winter Scripting Games: Pairing Off

Since 2005 Microsoft sponsors an annual scripting competition called **Winter Scripting Games**, whose competitors are given a series of exercises to be solved with **VBShell**, **Powershell** or **Perl** scripts.

I confess that I only discovered this competition a couple of days ago, and I think that some of the proposed exercises can be useful to practice F# as I'm doing with **Project Euler**.

There are **two Divisions** (Beginner and Advanced) with 10 problems each, and today we'll try to solve the first exercise of the Beginner division, called **Pairing Off**:

In this event we’ll be working with a standard deck of playing cards. A standard deck consists of four suits: Hearts, Spades, Clubs, and Diamonds. Within each suit are the numbers two through ten, plus a Jack, a Queen, a King, and an Ace.

Given a random set of five cards, your task is to find out how many pairs are in that set. In other words, if your five cards are the 2 of hearts, the 4 of spades, the 4 of clubs, the queen of diamonds and the queen of spades, you have 2 pairs: 2 fours and 2 queens. As another example, you might have a 3 of clubs, a 3 of diamonds, a 3 of hearts, a 10 of spades and an ace of hearts. In that case you have 3 pairs: 3 of clubs and 3 of diamonds; 3 of diamonds and 3 of hearts; and 3 of clubs and 3 of hearts.

Let's write the F# solution and then we'll comment it line by line:

#light open System let deck = [| for y in ["Hearts"; "Spades"; "Clubs"; "Diamonds"] for x in [1 .. 13] -> (x,y) |] let swap a i j = let t = a.[i] a.[i] <- a.[j] a.[j] <- t let shuffle a = let rand = new Random() Array.iteri (fun i _ -> swap a i (rand.Next(Array.length a))) a let rec pairs elem list = match list with | [] -> 0 | x::xs when (fst x) = elem -> 1 + pairs elem xs | x::xs -> pairs elem xs let rec count_pairs hand = match hand with | [] -> 0 | x::xs -> pairs (fst x) xs + count_pairs xs do shuffle deck let hand = deck |> Seq.to_array |> Seq.take 5 let answer = hand |> count_pairs

First of all we need to simulate a *deck* of cards, with **four suits** and **13 cards** for each suit, and this is done at line 4 thanks to **array comprehension**.

We need now to **shuffle the deck**, in order to randomly get five different cards every time we run the application. To do so, we defined the *shuffle* function at line 13, which swaps the elements of an array in-place, i.e. without returning a new object.

In fact the *shuffle* function is of type *array -> unit*, and *unit* is a special type that means "no value".

When this function is applied to our deck, it iterates each element and swaps it with a random selected one from the same array, using the *swap* function defined at line 8.

Since the *shuffle* function doesn't return anything, to call it we have a special syntax: instead of "*let*" we have to use the "*do*" keyword, as in line 28.

We are now able to create a card deck and shuffle it, the next step will be writing a function to count the number of pairs contained in a hand of cards.

To accomplish this task we have two functions, called *count_pairs* and *pairs*. The idea is to take the first card and check how many couples can be formed with the cards next to it.

The *count_pairs* function simply applies the *pairs* function to each element of the *hand* array, and the *pairs* function counts how many times the numeric part of the given card is equal to the number contained in the other cards.

To get our answer we just create a random hand of five cards and then apply the *pairs_count* function to it.

Nice, isn't it? Please let me know if you liked this article and you'd like to read some other on this topic, I'll be glad to write more.

### Twitter Updates

- @avalaxy Unfortunately I don't have an ETA. Feel free to submit patches or add suggestions to reach the goal sooner 2012-09-28
- @avalaxy it is planned for the new APIs and the library work is tracked at http://t.co/tAOfAYTA 2012-09-28
- @Sabrina_Miso Prova con uno zaino, non sara' trendy come una borsa, ma almeno le spalle non moriranno :) 2012-09-24
- @duplikey come hai fatto a resistere due giorni? 2012-09-24
- @avalaxy sorry, never tried that on a Metro app. Have you tried building the source instead? 2012-09-09
- More updates...