CS61A, Spring 1995
Midterm #2
Question 1 (2 points):
What will Scheme print in response to the following expressions? Also,
draw a ``box and pointer'' diagram for the result of each expression:
(cddaar '(((a b c d e) (f g h i j))
((l m n o p) (q r s t u))))
(cons '(a b) (append '(c d) '(e f)))
Question 2 (2 points):
Each of the following expressions, when evaluated, returns a list. Identify
the type (e.g., procedure, non-numeric word, list, number) of the
last element in each of the lists.
'(list (count 'hello))
'(list count)
(list 'count count)
(list 'hello (count 'hello))
Question 3 (5 points):
This question concerns the tree abstract data type, as defined by
these selectors and constructor:
(define datum car)
(define children cdr)
(define make-node cons)
Write the higher-order procedure tree-accumulate. Its two arguments
are a function fn and a tree. The function fn will take two
arguments and will be associative. (That is, you don't have to worry about
the order in which you find the nodes in the tree.) Tree-accumulate
will combine all of the datum elements in the tree by applying
fn
to them two at a time, analogous to ordinary accumulate. For example:
> (define my-tree
(make-node 3 (list (make-node 4 '())
(make-node 7 '())
(make-node 2 (list (make-node 3 '())
(make-node 8 '()))))))
> (tree-accumulate + my-tree)
27
> (tree-accumulate max my-tree)
8
Respect the tree data abstraction!
Hint: The book's version of accumulate has an extra argument
to provide a return value for the case in which no numbers are in
the range of values provided. We don't need that here, because a
tree always has at least one node, so there is always at least one
value available. If you only have one value, just return that
value; the function fn would require two arguments.
Be sure to get the base cases right!
Hint: Write a helper procedure called forest-accumulate.
Question 4 (5 points):
Given below is code from Abelson and Sussman for representing
a set of numbers as an unordered list and as an ordered list.
The names have been changed to reflect the underlying representations.
(define (element-of-unordered-set? x set)
(cond ((null? set) #f)
((equal? x (car set)) #t)
(else (element-of-unordered-set? x (cdr set)))))
(define (adjoin-unordered-set x set)
(if (element-of-unordered-set? x set)
set
(cons x set)))
(define (element-of-ordered-set? x set)
(cond ((null? set) #f)
((= x (car set)) #t)
((< x (car set)) #f)
(else (element-of-ordered-set? x (cdr set)))))
(define (adjoin-ordered-set? x set)
(cond ((null? set) (cons x set))
((= x (car set)) set)
((< x (car set)) (cons x set))
(else (cons (car set) (adjoin-ordered-set? x (cdr set)))) ) )
(a) Define constructors make-empty-unordered-set
and make-empty-ordered-set that use manifest types to
allow distinguishing between the two set representations.
(b) Define a procedure element-of-set? that uses data-directed
programming to choose the correct element-of-... procedure
to determine if a given word is an element of a given set.
That is, your procedure should still work, unchanged, if we later invent
another representation for sets.
Question 5 (5 points):
This two-part question is about data-directed programming. We are going to
use a list to represent a finite state machine (FSM) like this:

The numbered circles represent the states of the machine. At any moment
the machine is in a particular state. The machine reads words, one letter at
a time. If the machine is in some state, and sees a certain letter, it follows
the arrow from its state with that letter as its label, and ends up in a new
state. For example, if the machine above is in state 1 and it sees the letter
B, it goes into state 3.
We'll represent a FSM by a list of all its transition arrows. The machine
above has six such arrows:
((1 A 2) (1 B 3) (1 C 4) (2 A 1) (3 B 1) (4 C 1))
If the machine reads a letter for which there is no applicable arrow, it should
enter state number 0. In effect, there are ``invisible'' arrows like (2 C 0)
that needn't be represented explicitly in the list.
(a) Write a function transition that takes three arguments: a FSM
list, a current state number, and a letter. The function should return the new
state. For example, if fsm represents the list above, we should be
able to do this:
> (transition fsm 1 'C)
4
> (transition fsm 2 'C)
0
(b) We want an FSM to process words, not just single letters. The machine
``reads'' the word one letter at a time. Our sample FSM, starting in state 1,
should process the word AACCAAB by going through states 2, 1, 4, 1, 2, 1, and
3. The final state, 3, is the result of processing the word.
Write a function process that takes as its arguments a FSM, a
starting state number, and a word. It should return the ending state:
> (process fsm 1 'AACCAAB)
3
> (process fsm 1 'AAAC)
0
Take a peek at the
solutions