CS61A, Fall 1994
Midterm #2
Question 1 (4 points):
What will Scheme print in response to the following expressions? Also,
draw a ``box and pointer'' diagram for the result of each expression:
(cons (append '(a b) '(c d)) '(e f))
(list (cons 'a 'b) (list 'c 'd) 'e)
(caaddr '((a b c d e) (f g h i j) (l m n o p) (q r s t u)))
(cons 'a (cdr '(((b)))))
Question 2 (5 points):
Recall that the definition of a list is that it's either the
empty list or a pair whose cdr is a list. This definition says nothing
about the elements of the list. For example,
(1 2 (3 . 4) (5 . 6) 7)
is a list of five elements, even though two of the elements are pairs
that aren't lists.
We'll define a deep list as a list in which every element is
either a deep list or not a pair. Equivalently, a deep list is a
structure made of pairs in which the cdr of every pair, including
the ones in the elements, is a list.
Write the predicate deep-list? that takes any Scheme object as
its argument, returning #t if the argument is a deep list.
Question 3 (5 points):
We want to write a program that uses the time of day as an abstract
data type. We'll represent times internally as a list of three elements,
such as (11 23 am) for 11:23 am. For the purposes of this problem,
assume that the hour part is never 12, so there's never any special
problems about noon and midnight. The hour will be a number 1--11,
the minute will be a number 0--59, and the third element (which we'll
call the category) must be the word am or the word pm.
Here's our implementation:
(define (make-time hr mn cat) (list hr mn cat))
(define hour car)
(define minute cadr)
(define category caddr)
(a) This is a good internal representation, but not a good representation
for the user of our program to see. Write a function time-print-form
that takes a time as its argument and returns a word of the form
3:07pm.
(b) If we want to ask whether one time is before or after another, it's
convenient to use the 24-hour representation in which 3:47 pm has the form
1547. Write a procedure 24-hour that takes a time as its
argument and returns the number that represents that time in 24-hour
notation:
> (24-hour (make-time 3 47 'pm))
1547
Respect the data abstraction!
(c) Now we decide to change the internal representation of
times to be a number in 24-hour form. But we want the constructor and
selectors to have the same interface so that programs using the
abstract data type don't have to change. Rewrite the constructor
and selectors to accomplish this.
Question 4 (5 points):
The example of message passing on page 141 deals only with functions of
one argument, such as the magnitude of a complex number. In this problem
our goal is to extend the idea of message passing to two-argument
functions like addition. We want to do this without violating the spirit
of ``intelligent data objects''; that is, a complex number should know
how to add itself to another one.
We define the two-argument functions in the following form:
(define (+complex z1 z2)
((z1 'add) z2))
Your job is to modify make-rectangular so that complex numbers
understand this new message. For your convenience here is the code
from the book:
(define (make-rectangular x y)
(define (dispatch m)
(cond ((eq? m 'real-part) x)
((eq? m 'imag-part) y)
((eq? m 'magnitude)
(sqrt (+ (square x) (square y))))
((eq? m 'angle) (atan y x))
(else
(error "Unknown op -- MAKE-RECTANGULAR" m))))
dispatch)
Take a peek at the
solutions