This lab assignment calls on you to write a number of different function definitions in SML. You are to turn in the code you write and the type that was inferred for each function. You do not need to turn in any evidence of your testing, although you should be sure to test each function as you write it.
A perfect shuffle of a standard deck of 52 playing cards consists of cutting the deck in half (so that the first 26 cards are in one half and the remaining cards are in the other half) and then interleaving the two groups of cards, so that the cards alternately come from the two halves, starting with the first card from the first half. The same process applies for decks of sizes other than 52, although one detail arises for decks with an odd number of cards: we need a convention for what it means to split the deck in half. We'll assume that the first half gets the extra card, so that in a deck of 5 cards, for example, the first three cards are the first half and the remaining two cards are the other half.
Magicians and group theorists have figured out that eight perfect shuffles restores a deck of 52 cards back to its original configuration. Similar results hold for other sizes of decks, though the shuffle number varies with the deck size. In this lab, you will use ML programming in order to explore perfect shuffles.
In order to run the Standard ML system on one of the MCS department
machines, you should use the sml
command in a shell
(terminal) window. This should behave approximately as shown in the
textbook. Be sure to ask for help if you need it. The error messages
are often quite inscrutable. One easy thing to try when faced with a
strange error message is to more fully parenthesize your code. Many
beginners run into trouble because ML's default grouping isn't what
they expect. ML is like ordinary math notation
in that extra parentheses never hurt.
Although you could in principle type your function definitions
directly into the sml
system, you would be better off
putting them in a file and loading that file in, I will show you how to do that during lectures.
When working on your own, you can certainly install SML/NJ on your own laptop (SML/NJ stands for the Standard ML of New Jersey, there should be plenty of tutorials online to help you with installations). Alternatively, you can use an emulator available online. I can show you some during lectures as well.
The obvious representation of a deck of cards is as a list.
Later we'll see how the elements of the list can be structured values
that contain suits and ranks (for example, a 3 of hearts). For now,
it will suffice to just use a list of consecutive integers, such as
the list of integers from 1 to 52. That list should be restored to
its original order by 8 perfect shuffles, just as much as a list of
actual cards would be. To produce lists like this, write a function
intsFromTo
. It should take a pair of integers,
low and high, and return an list of consecutive
integers in ascending order, namely all those that are greater than or
equal to low and less than or equal to high.
(Under some circumstances, this may be an empty list.)
For use in selecting the first half of a deck of cards (i.e., a
list), define a function, take
, that is passed a pair
consisting of a list and the number of elements that should be taken
from the front of the list. For example,
take([10,20,30,40,50],3)
would evaluate to
[10,20,30]
.
For use in selecting the second half of a deck of cards (i.e.,
a list), define a function, drop
, that is passed a pair
consisting of a list and the number of elements that should be dropped
from the front of the list. For example,
drop([10,20,30,40,50],3)
would evaluate to
[40,50]
.
The next function you need to define is one to
interleave
a pair of lists. For example,
interleave([1,2],[10,20])
would evaluate to
[1,10,2,20]
. The first list may have one more element in it than the second list does; be sure your procedure works in this case as well.
Now you can put together take
, drop
,
and interleave
in order to write a function called
shuffle
that takes a list and returns the result of
performing one perfect shuffle on it. I suggest you read
Section 7.8 if you haven't yet; you will be able to make good use
of a local variable definition. Be sure you get right the case where
the length of the list is odd.
To test that 8 perfect shuffles returns a deck to its original
configuration, you could manually type in shuffle
8
times, but that would be boring. Instead define a function
multipleShuffle
that could be used as follows:
multipleShuffle(intsFromTo(1,52),8)
intsFromTo
, take
, drop
, interleave
, shuffle
, and multipleShuffle
) into a text document and save the document as "shuffle.sml
". Submit the file via Moodle.
Finally, if you use pattern matching in task 2 - 6 of your functions (instead of if/else
statements), you will earn an extra 5 bonus points. I will give you some examples of pattern matching during lectures. My suggestion is for you to write all of your (six) functions using if/else
statements first.
shuffle.sml
via Moodle.