MCS-178 Project 4 (Spring 2023): An Introduction to ML Programming

Start: Thursday 3/23; Due: Wednesday 4/12, by the beginning of class

What you are to turn in

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.

Background

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.

Technical details

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.

Specific tasks

  1. 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.)

  2. 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].

  3. 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].

  4. 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.

  5. 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.

  6. 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)

What you must hand in

Copy and paste the 6 functions you had written (intsFromTo, take, drop, interleave, shuffle, and multipleShuffle) into a text document and save the document as "shuffle.sml". Submit the file via Moodle.

Grading

The project is worth a total of 30 points. Each function is worth a total of 5 points. For each function, the correctness of the function is worth 3/5 points. Your functions should not be convoluted and overly complicated; the complexity of each function is worth 2/5 points.

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.

Submission

Use the same procedure to submit your code as in the previous project. Submit shuffle.sml via Moodle.