15-212-X : Homework Assignment 3
Due Wed Oct 8, 2:00pm (electronically); papers at recitation.
Maximum Points: 100 (+20 extra credit)
signature DICT = sig type key = int * int type 'a entry = key * 'a type 'a dict val empty : 'a dict val lookup : 'a dict -> key -> 'a option val insert : 'a dict * 'a entry -> 'a dict val delete : 'a dict * key -> 'a dict val map : 'a dict -> ('a -> 'b) -> 'b dict val fold : 'a dict -> ('a * 'b * 'b -> 'b) -> 'b -> b' val exists : 'a dict -> ('a entry -> bool) -> bool end; (* signature DICT *)There is a partial implemenation of a structure
BinarySearchTree
with this
signature in the file dict.sml. Plese extend this
structure according to the following specifications.
map d f
should go through the
whole dictionary
d and apply the function f to every entry,
creating a new dictionary. Write the function map
.
fold d f init
should go through the binary tree d
and return
init
if it encounters a leaf. For every other node in the tree
it should return f(datum,vLeft,vRight)
where
datum is the datum of the node, and vLeft is the
result of applying fold
on the left subtree,
vRight is the result of applying fold
on the right
subtree. Write the function
fold
.
exists d p
should return
true
if there is an entry in the database satisfying the
predicate p,
false
otherwise. Write the function exists
.
delete (d, k)
should return a
dictionary d' in which a possible entry with key k has
been removed. If there is no such entry, d' should be
d. Make sure the invariant on binary search trees is preserved
under this operation.
Another company is interested in purchasing CMU's dictionary package: GAMESoft intends to implement the PEG solitaire game. The PEG solitaire game is best described as follows: A PEG board contains 15 holes, shaped in form of a triangle. Every hole can be addressed by a pair of coordinates.
Initially 14 of the holes are filled with pegs . That means there is one empty hole somewhere on the
board. In our example it is (1,2)
, which is the standard
initial board.
During the game it is possible to take a peg, jump over a peg into an empty hole. The peg that was jumped over is then removed from the board. It is important that
The goal of the peg solitaire game is to jump pegs in such a way that only one peg remains on the board eventually.
Initially GAMESoft was only interested in purchasing CMU's dictionary
package. But because of its nice implementation, GAMESoft decided to ask
you for programming help. Here is what the company has already done using
the signature DICT
from above:
structure Dict :> DICT = BinarySearchTree; datatype square = Peg | Hole; type board = square Dict.dict; structure Dir = struct datatype direction = East | NorthEast | NorthWest | West | SouthWest | SouthEast fun increment (East) = (1,0) | increment (NorthEast) = (0,1) | increment (NorthWest) = (~1,1) | increment (West) = (~1,0) | increment (SouthWest) = (0,~1) | increment (SouthEast) = (1,~1) fun exists p = p East orelse p NorthEast orelse p NorthWest orelse p West orelse p SouthWest orelse p SouthEast end; fun initialize (i,j) b = next (i,j) (Dict.insert (b,((i,j),Peg))) and next (0,0) b = b | next (i,0) b = initialize (i-1,5-i) b | next (i,j) b = initialize (i,j-1) b; val fullBoard = initialize (4,0) (Dict.empty);See the file solitaire.sml for this code.
solve : int -> board -> bool
, where
solve n b
returns true
if there is a
possibility to make n consecutive moves otherwise false
.
That means if solve 13
applied to the initial
board returns true
then there is a way
to remove all but one peg. Is your implementation efficient enough
to determine that there cannot be 14 consecutive moves?
solution
containing enough information
so that a sequence of moves can easily be replayed from it.
Generalize the function from Question 2.1 to a function
findSolution : int -> board -> solution optionwhich returns the first found solution or
NONE
for the
given number of moves n. Check the solution
returned by findSolution 13
on the standard initial board.
R
:
r1 r2
One
r1 + r2
Zero
r*
datatype regexp = Char of char | Times of regexp * regexp | One | Plus of regexp * regexp | Zero | Star of regexp;From time to time it is helpful to have some more constructs available to form regular expressions, such as
L(_) = {a | a is a character in the alphabet}
Underscore
.
L(r1 & r2) = {s | s in L(r1) and s in L(r2)}
And
.
L(T) = {s | s is a string over the alphabet}
Top
.
L(~ r) = {s | s not in r}
Not
.
accept
is available in the
file regexp.sml and should be extended
to deal with these new constructors. Remind yourself of the
specification of the acc
function and make sure your new
cases fit this specification. You should also generate some test data
to validate your implementation.
Note that for the purposes of our implementation, the alphabet is simply
any ML value of type char
.
/afs/andrew/scs/cs/15-212-X/studentdir/<your andrew id>/ass3/