This preview shows page 1. Sign up to view the full content.
Unformatted text preview: CS 61A Final  May 20, 1994 Your name login cs61a{ This exam is worth 30 points, or 17% of your total course grade. The exam contains eight questions, but you need only answer six of them! You must answer all of questions 1{4. Then there are two pairs of questions. Answer 5A or 5B, and 6A or 6B. Indicate below which you answered:
I answered 5 and 6 . (Fill in A or B.) This booklet contains sixteen numbered pages (both sides of six sheets) including the cover page. Put all answers on these pages, please; don't hand in stray pieces of paper. This is an open book exam. When writing procedures, write straightforward code. Do not try to make your program slightly more e cient at the cost of making it impossible to read and understand. When writing procedures, don't put in error checks. Assume that you will be given arguments of the correct type.
Our expectation is that many of you will not complete one or two of these questions. If you nd one question especially di cult, leave it for later; start with the ones you nd easier. 1 2 3 4 5 6 total 1 =5 =5 =5 =5 =5 =5 =30 Question 1 (5 points):
Draw a \box and pointer" diagram for the following Scheme expressions: a (1 point).
(let ((x (cons '() '()))) (setcar! x x) (setcdr! x x) x) b (2 points).
(define (funny! x) (if (null? x) '() (let ((temp (cdr x))) (funny! temp) (setcdr! x (car x)) (setcar! x temp) x))) (funny (list 1 2)) Question continues on next page.
2 Your name login cs61a{ Question 1 continued
c (2 points). Write a Scheme expression to construct the following structure. 3 Question 2 (5 points):
We are going to create an abstract data type called a ternary tree. It's just like a binary tree, except that each node can have a left branch, a middle branch, and a right branch. (Any of these might be empty for a particular node.) We are going to represent a node using three pairs, arranged like this: (a) Write the constructor (maketernary datum left middle right); the selectors datum, leftbranch, middlebranch, and rightbranch; and the mutators setdatum!, setleftbranch!, setmiddlebranch!, and setrightbranch!. (b) Write a procedure flip that takes a ternary tree as its argument, and mutates the tree so that the left and right branches of every node are interchanged. (Don't move the middle branch.) Respect the data abstraction. 4 Your name login cs61a{ Question 3 (5 points):
The following program has two kinds of errors: violations of data abstraction (that work but are bad style) and downright bugs. Fix them and indicate which are which. We are dealing with international nance and so we have amounts of money with manifest type to indicate the currency unit. (Note: none of the errors are about unbalanced parentheses!)
(define attachtype cons) (define type car) (define contents cdr) (define (makedollar amt) (attachtype 'dollar amt)) (define (makefranc amt) (attachtype 'franc amt)) (define (makepound amt) (attachtype 'pound amt)) (define (+money amt1 amt2) (makedollar (+ (contents (dollarize amt1)) (contents (dollarize amt2))))) (define (dollarize amt) (* (conversion (car amt)) (cdr amt))) (define (conversion type) (cond ((eq? type 'dollar) 1.0) ((eq? type 'franc) 0.2) ((eq? type 'pound) 2.0))) 5 Question 4 (5 points):
Write a function regroup whose argument is a list structure L containing nonnegative integers. Its return value should be a function that, given the list (0 1 2 3 4 ...) as argument, would return L. For example:
> (define f (regroup '((0 1) 4 (2 3)))) > (f '(the fool on the hill)) ((THE FOOL) HILL (ON THE)) > ((regroup '(1 0 3 2 5 4)) '(being for the benefit of mister kite)) (FOR BEING BENEFIT THE MISTER OF) Another way to say it is that each number in the argument to regroup indicates the starting position of an element in the argument to the returned function. 6 Your name login cs61a{ Question 5A (5 points):
We are going to use OOP to simulate tape players and tapes. We can put a tape into a player, play it, fast forward it, and rewind it. (a) We'll represent the music on a tape as a sentence containing the lyrics:
> (define help! (instantiate tape '(Help! I need somebody Help! not just ...))) Each tape will also remember its position within that sentence. (Its initial position is before the rst word.) A tape accepts two messages, left and right. Left means to move one position toward the beginning of the tape, returning the word passed over. Right is the same, but moving toward the end:
> (ask HELP! > (ask I > (ask NEED > (ask NEED help! 'right) help! 'right) help! 'right) help! 'left) If the tape is asked to move past the beginning or end of its sentence, it should return #f and not move. Implement the tape class in OOP notation. This question continues on the next page.
7 Question 5A continued.
eject (b) A tape player understands the messages . Here's how they work: load play fastforward rewind , , , , and > (define sony (instantiate tapeplayer)) > (ask sony 'load help!) LOADED > (ask sony 'play 5) (HELP! I NEED SOMEBODY HELP!) > (ask sony 'play 3) (NOT JUST ANYBODY) > (ask sony 'fastforward 4) OK > (ask sony 'play 3) (NEED SOMEONE HELP!) > (ask sony 'rewind) OK > (ask sony 'play 3) (HELP! I NEED) > (ask sony 'load shelovesyou) ERROR  TAPE ALREADY LOADED > (ask sony 'eject) OK > (ask sony 'load shelovesyou) LOADED > (ask sony 'play 5) (YOU THINK YOU LOST YOUR) ;; play five words ;; play three more words ;; skip over four words ;; "help! you know I"] ;; back to the beginning Implement the tapeplayer class in OOP notation. You may continue your answer on the following (blank) page, if needed.
8 Your name login cs61a{ Continue your answer to question 5A here. 9 Question 5B (5 points):
We're going to use streams for signal processing. Suppose you have an irreplaceable old, scratchy record, and you'd like to clean up the clicks and pops. First you digitize the information on the record, producing a stream of the voltages at each sampling interval (usually 44,000 per second, if the result will be recorded on a CD). Then we eliminate clicks by processing this stream using three procedures: The rst procedure, differences, takes a stream of numbers as its argument and returns a stream of the di erences between successive elements of the argument. If we represent a stream as element1 element2 ...] then here's an example:
> (differences 0 5 8 6 3 7 26 9 5 ...]) 5 3 2 3 4 19 17 4 ...] The second procedure, limit, takes as its arguments a stream of numbers and a limiting number. It returns a copy of its argument stream, but with every number greater than the limit replaced by the limit, and every number less than the negative of the limit replaced by the negative of the limit:
> (limit 5 3 2 3 4 19 17 4 ...] 6) 5 3 2 3 4 6 6 4 ...] The third procedure, sums, takes a stream of numbers as argument and returns a stream containing partial sumsthat is, the rst number, then the sum of the rst two numbers, then the sum of the rst three, and so on:
> (sums 5 3 2 3 4 6 6 4 ...]) 5 8 6 3 7 13 7 3 ...] Sums is essentially the inverse of di erences. For any stream s, (sums (differences (consstream 0 s))) will be the same as the original s. With these tools we can write a declicking procedure:
(define (declick strm limitvalue) (sums (limit (differences strm) limitvalue))) Your job is to write differences, limit, and sums. Continue your answer on the following (blank) page.
10 Your name login cs61a{ Continue your answer to question 5B here. 11 Question 6A (5 points):
Write a logic program to implement the remove relation that holds if one list is a copy of another with a particular value removed:
query==> (remove a (a b a c a d e f a x) ?what) (REMOVE A (A B A C A D E F A X) (B C D E F X)) DONE query==> (remove ?what (a b c a d e a b d) (a c a d e a d)) (REMOVE B (A B C A D E A B D) (A C A D E A D)) DONE query==> (remove (REMOVE A (A B C (REMOVE B (A B C (REMOVE C (A B C (REMOVE D (A B C (REMOVE E (A B C DONE ?element (a b c A D E A B D) (B A D E A B D) (A A D E A B D) (A A D E A B D) (A A D E A B D) (A a C C B B B d D A A C C e E D D A A a B E E E D b d) ?result) D)) A D)) A B D)) A B)) A B D)) Do not use lispvalue! You may use the following rule:
(rule (same ?x ?x)) 12 Your name login cs61a{ Question 6B (5 points):
Sometimes you're writing a program and you can't nd your bug, but you know that the value of a particular variable is changing to some wrong thing. But you don't know quite when the set! that changes the value is happening. What you'd like is to be able to say, \Whenever this variable changes its value, invoke this procedure with the old and new values as arguments." The procedure might print a message to help you debug, for example. A variable with this magic behavior is called an active variable. We'd like to be able to do this:
> (define x 17) > (activate x (lambda (old new) (print "Changing x from ") (princ old) (princ " to ") (princ new) (+ new 2))) > x 17 > (set! x 3) CHANGING X FROM 17 TO 3 > x 5 As this example shows, the new value of the variable should be whatever value the procedure returns. (a) Is this primarily a change to eval or to apply? (b) What speci c procedure(s) will you change? (c) Make the changes on the following pages. This question continues on the following page.
13 Question 6 continued:
(define (eval exp env) (cond ((selfevaluating? exp) exp) ((quoted? exp) (textofquotation exp)) ((variable? exp) (lookupvariablevalue exp env)) ((definition? exp) (evaldefinition exp env)) ((assignment? exp) (evalassignment exp env)) ((lambda? exp) (makeprocedure exp env)) ((conditional? exp) (evalcond (clauses exp) env)) ((application? exp) (apply (eval (operator exp) env) (listofvalues (operands exp) env))) (else (error "Unknown expression type  EVAL" exp)))) (define (apply procedure arguments) (cond ((primitiveprocedure? procedure) (applyprimitiveprocedure procedure arguments)) ((compoundprocedure? procedure) (evalsequence (procedurebody procedure) (extendenvironment (parameters procedure) arguments (procedureenvironment procedure)))) (else (error "Unknown procedure type  APPLY" procedure)))) (define (listofvalues exps env) (cond ((nooperands? exps) '()) (else (cons (eval (firstoperand exps) env) (listofvalues (restoperands exps) env))))) (define (evalsequence exps env) (cond ((lastexp? exps) (eval (firstexp exps) env)) (else (eval (firstexp exps) env) (evalsequence (restexps exps) env)))) This question continues on the following page.
14 Your name login cs61a{ Question 6 continued:
(define (extendenvironment variables values baseenv) (adjoinframe (makeframe variables values) baseenv)) (define (adjoinframe frame env) (cons frame env)) (define (makeframe variables values) (cond ((and (null? variables) (null? values)) '()) ((null? variables) (error "Too many values supplied" values)) ((null? values) (error "Too few values supplied" variables)) (else (cons (makebinding (car variables) (car values)) (makeframe (cdr variables) (cdr values)))))) (define (makebinding variable value) (cons variable value)) (define (makeprocedure lambdaexp env) (list 'procedure lambdaexp env)) (define (makebinding variable value) (cons variable value)) (define (bindingvariable binding) (car binding)) (define (bindingvalue binding) (cdr binding)) (define (setbindingvalue! binding value) (setcdr! binding value)) This question continues on the following page.
15 Question 6 continued:
(define (lookupvariablevalue var env) (let ((b (bindinginenv var env))) (if (foundbinding? b) (bindingvalue b) (error "Unbound variable" var)))) (define (bindinginenv var env) (if (nomoreframes? env) nobinding (let ((b (bindinginframe var (firstframe env)))) (if (foundbinding? b) b (bindinginenv var (restframes env)))))) (define (extendenvironment variables values baseenv) (adjoinframe (makeframe variables values) baseenv)) (define (setvariablevalue! var val env) (let ((b (bindinginenv var env))) (if (foundbinding? b) (setbindingvalue! b val) (error "Unbound variable" var)))) (define (definevariable! var val env) (let ((b (bindinginframe var (firstframe env)))) (if (foundbinding? b) (setbindingvalue! b val) (setfirstframe! env (adjoinbinding (makebinding var val) (firstframe env)))))) (define (evalassignment exp env) (let ((newvalue (minieval (assignmentvalue exp) env))) (setvariablevalue! (assignmentvariable exp) newvalue env) newvalue)) (define (evaldefinition exp env) (definevariable! (definitionvariable exp) (minieval (definitionvalue exp) env) env) (definitionvariable exp)) 16 ...
View Full
Document
 Fall '08
 Harvey
 Computer Programming

Click to edit the document details