CS61A, Spring 1994
Midterm #3
Question 1 (4 points):
What will the Scheme interpreter print in response to each of the following
expressions? Also, draw a ``box and pointer'' diagram for the result of
each expression. Hint: It'll be a lot easier if you draw the box and
pointer diagram first!
(let ((x (list 1 2 3 4)))
(set-cdr! (cdr x) (cdddr x))
x)
(let ((x (list 1 2 3 4)))
(set-car! (cdr x) (cadr x))
x)
(let ((x (list 1 2 3 4)))
(set-cdr! (cdr x) (car x))
x)
(let ((x (list 1 (2 3) 4)))
(set-car! x (cadr x))
x)
Question 2 (5 points):
Write deep-subst!, a procedure that takes three arguments, two of
which are words and the third of which is any list structure (anything made
of pairs). It should mutate the list structure so that any occurrence of
the first argument, however deep in sublists, is replaced by the second
argument. Examples:
> (deep-subst! 'foo 'baz (list (cons 'hello 'goodbye) (cons 'moby 'foo)))
((hello . goodbye) (moby . baz))
> (deep-subst! 'a 'x (list (list 'a 'b 'c) (list 'b 'a 'd)
(list 'f 'a 'b)))
((x b c) (b x d) (f x b))
Do not allocate any new pairs in your solution!
Question 3 (5 points):
We are simulating a read-only memory (ROM) in the OOP system:
(define-class (rom values)
(default-method
(if (and (number? message) (< message (length values)))
(nth message values)
(error "Bad ROM address"))))
> (define sample-rom (instantiate rom '(4 5 9 23))
> (ask sample-rom 2)
9
> (ask sample-rom 7)
ERROR -- Bad ROM address
Now we want to make a programmable ROM (PROM). Unlike a standard
ROM, a PROM starts with nothing stored in it, although it does have
a fixed size that is set when the PROM is built. You can put a
value into each address, but only once---you can't change the
value later. We want to implement the prom class so that it
takes the size as its instantiation variable, but inherits from
the rom class:
(define (prom size)
(parent (rom ((repeated (lambda (vals) (cons '() vals)) size)
'())))
...)
It should accept a SET message that takes an address (a number) and
a value (anything) as arguments. If the prom is big enough to have
such an address, but the value in that address is the empty list,
then the new value should be put in that address.
> (define this-prom (instantiate prom 6))
> (ask this-prom 3)
()
> (ask this-prom 'set 3 'foo)
> (ask this-prom 3)
FOO
> (ask this-prom 'set 9 'baz)
ERROR -- Bad ROM address
> (ask this-prom 'set 3 'garply)
ERROR -- PROM address already has value
Complete the definition of the prom class. If possible, do it
without modifying the definition of the rom class. If you must
modify the rom definition, explain why.
Question 4 (5 points):
Quite a while ago you saw this procedure to get from one row of
Pascal's triangle (represented as a sentence of numbers) to the next:
(define (next-row row)
(define (iter old)
(if (empty? (bf old))
'(1)
(se (+ (first old) (first (bf old)))
(iter (bf old)))))
(se 1 (iter row)))
> (next-row '(1 3 3 1))
(1 4 6 4 1)
(A) Rewrite next-row so that its argument and return value
are (finite) streams instead of sentences.
(B) Using your stream version of next-row, create the (infinite)
stream of all the rows of Pascal's triangle. (The first row of the
triangle just contains a single number 1.)
Take a peek at the
solutions