CIS-4/681 – Assignment 1 – LISP

advertisement
CIS-4/681 – Assignment 1 – LISP
Due: Tuesday, September 28 – 2 weeks
This assignment asks you to write a number of simple lisp functions which manipulate lists in various ways.
The material you hand in should include both the function definitions and the results of applying the functions
to some test data. Keep in mind that you should be writing your functions recursively with no use of setf, prog,
or goto’s.
The material you hand in should include both the function definitions and the results of applying the functions
to some test data. It is easiest if you can show your testing results just after the function definitions on your
hard copy. One way is to use the function print-eval which would allow you to specify all of your test cases and
then run them. You will find this function (and documentation for how to use it) in the lisp-init.lisp file. You
will need to print out the lisp-listener buffer after running print-eval, and then you could cut-and-paste them
into your file for handing in.
Other methods also work, but most require some cutting and pasting.
Please be sure to remember that falsifying the output of your program is a serious breach of
the code of ethics and will be dealt with severely.
In addition to the hard-copy that you hand in, you should send an electronic version of your lisp file only
(i.e., no test cases) to trnka@cis.udel.edu. This will allow the TA (Keith) to run your functions if necessary.
Please be careful that you use the exact function names given in this assignment to make grading easier. Again,
the lisp functions in the soft-file must match the ones on the hard copy exactly, otherwise it is a
serious violation of the code of ethics.
1. Ordered Binary Trees in Lisp – 15 points – It is quite easy to represent ordered binary trees using lisp
lists. We can let nil represent the empty binary tree and the list of three elements (info left right) represent
a binary tree whose information is info, whose left child is the binary tree left and whose right child is the
binary tree right. Recall that an ordered binary tree is one where at each node in the tree, all information
to the left of a node is less than (or equal to) info and all information to the right of a node is greater than
info. For example, the following ordered binary tree:
7
/ \
/
5
/ \
/
-2
\
9
\
6
\
\
12
might be represented as follows:
(7 (5 (-2 nil nil)
(6 nil nil))
(9 nil
(12 nil nil)))
This problem asks you to write a number of functions to build and access ordered binary trees where an
integer is stored at each node in the tree. Write the following functions:
(a) (is-in-tree? n bt) – this function returns T if the integer n is in the ordered binary tree bt. It
returns nil otherwise. (Note: the search should be intelligent in that it should take advantage of the
fact that bt is an ordered binary tree!)
(b) (insert n bt) – this function returns a new ordered binary tree formed by adding the integer n to
the ordered binary tree bt.
1
(c) (insert-list list-of-integers bt) – this function returns the ordered binary tree formed by inserting
each of the integers in list-of-integers into the ordered binary tree bt. The integers are inserted in left
to right order.
(d) (make-bt list-of-integers) – this function returns an ordered binary tree formed from the list of
integers in the given order.
Some examples are:
(setf t1 (make-bt ’(2 1 3))) ---> (2 (1 nil nil) (3 nil nil))
(setf t1 (insert 4 t1)) ---> (2 (1 nil nil) (3 nil (4 nil nil)))
2. rep-seq – (5 points) – write a function that takes a list of positive integers as its argument and returns a
list of sublists where the ith sublist consists of the ith integer in the argument list repeated j times, where
j is the value of the ith integer. (Hint: You may want your function rep-seq to use another function rep
that takes two arguments, j and k, and returns a list containing k repetitions of argument j.) Example:
> (rep-seq ’(3 5 3 1))
((3 3 3)(5 5 5 5 5)(3 3 3)(1))
3. sum-numbers – (10 points) – write a function that takes an arbitrarily embedded list containing both
numbers and symbols that returns the sum of the numbers occurring (at any level) in the list. For example:
> (sum-numbers ’(1 a (b (c 3) (((4)) b) 5)))
13
4. (typer s-exp) – (10 points) – (from Brooks p2.5) write a function typer that takes an arbitrarily complex
s-expression and returns a new one with the same “shape” but with only symbols NUMBER and SYMBOL
corresponding to the type of the original atoms in the list. Examples:
> (typer ’(a b 3 d))
(SYMBOL SYMBOL NUMBER SYMBOL)
> (typer ’((a 2.3) (((b c)) 3)))
((SYMBOL NUMBER) (((SYMBOL SYMBOL)) NUMBER))
5. count-cells – (10 points) – write a function that computes the number of list cells a list uses. An atom
uses no cells. The empty list, nil, uses no cells. A list uses 1 cell for each of its members in addition to the
cells each of its members use. E.g.,
(count-cells
(count-cells
(count-cells
(count-cells
(count-cells
(count-cells
’(one two 3 4 5)) ---> 5
’(one (two) 3 4 5)) ---> 6
’(defun round (n) (fix (add n 0.5)))) ---> 10
nil) ---> 0
’(1 2 nil)) ---> 3
’one) ---> 0
6. pfeval – 15 points – write a function which takes a list containing a postfix expression and returns the value
of that expression. The evaluation of the postfix expression should use a stack which is easily implemented
as a list. You will probably want to write a helping function whose arguments are the stack and a (partial)
postfix expression to do the actual evaluation. You may assume that the postfix expression is well formed
and contains only numbers and the binary operators -, +, *, ^, and /. Example:
(pfeval ’(16 2 3 ^ / 4 5 * + 16 3 * -)) --> -26
2
7. mobilep – 15 points – (from Winston/Horn Problem 4-10) A mobile is a form of abstract sculpture
consisting of parts that move. Usually it contains objects suspended in mid-air by fine wires hanging from
horizontal beams. We can define a particularly simple type of mobile recursively as either a suspended
object, or a beam with a sub-mobile hanging from each end. If we assume that each beam is suspend from
its midpoint, then in order for the mobile to be balanced, the two submobiles hanging from a beam must
have the same weight.
We can represent such a mobile as a binary tree. Single suspended objects are represented by numbers
equal to their weight, while more complicated mobiles can be represented by a three-element list. The first
element is a number equal to the weight of the beam, while the other two elements represent sub-mobiles
attached at the two ends of the beam.
A mobile should be balanced. This means that the two mobiles suspended from opposite ends of each
beam must be equal in weight. Define mobilp, a function which determines whether a mobile is balanced.
It returns NIL if it is not, and its total weight if it is. (HINT: I used a let statement in my solution which
held the weight of the left and right mobiles.) So for example:
(mobilep ’(6 (4 (2 1 1) 4) (2 5 (1 2 2))))
---> 30
8. chomper – (20 points) – The purpose of this function is to mimic the actions of a simple cybernetic animal
that lives in a one-dimensional world of zeros and ones. Ones represent things to eat, and the animal seeks
them out and eats them until none are left.
An interaction with chomp might look like this:
>(chomper ’(0 1 0 1 0 0
(0 1 0
(0 1 0
(0 1 0
(0 1 0
(0 1 >
(0 > 0
(0 V 0
(0 < 0
(0 0 <
(0 0 0
(0 0 0
(0 0 0
(0 0 0
(0 0 0
(0 0 0
(0 0 0
That’s
NIL
1 0 0 > 1 1
1 0 > 0 1 1
1 > 0 0 1 1
> 0 0 0 1 1
0 0 0 0 1 1
0 0 0 0 1 1
0 0 0 0 1 1
0 0 0 0 1 1
0 0 0 0 1 1
< 0 0 0 1 1
0 < 0 0 1 1
0 0 < 0 1 1
0 0 0 < 1 1
0 0 0 0 < 1
0 0 0 0 0 <
0 0 0 0 0 V
all, folks.
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
V 1 1 0 0))
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
0)
Let’s notice a couple of things about the Chomper. First, Chomper itself is represented in one of three
ways, depending on its current state. If Chomper is not currently moving in a direction, it is represented
as a V. If it is moving left, it is represented as a >, and if it is moving right, a <. Thus the list given to
the chomper function consists of a series of zeros and ones and one instance of Chomper in one of its three
states.
Suppose Chomper is in its V state. Then, if there is any food to its left (i.e., there are any ones to its left)
then it will switch to a state in which it is moving left. If there is no food to its left (i.e., there are NO
ones to its left) but there is food to its right, it will switch to a state in which it is moving right. If there is
no food left for it to consume (when it is in its v state), it will print out the message That’s all folks.
and return nil.
3
Once Chomper is started in one direction or another, it will continue in that direction as long as there
is any food in that direction at all. When food runs out in that direction, Chomper will not move but
will switch into its V state. As long as there is food in a particular direction, Chomper will move one in
that direction, converting ones into zeros as they are met. The state of Chomper is printed out with each
change to its state.
You will need a number of helping functions with this procedure! I used a let to hold: (1) the list to the
left of chomper, (2) a list containing chomper itself, (3) the list to the right of chomper. Then the function
prints and returns different things depending on what chomper looks like and whether or not there is food
to its left or right.
4
Download