CISC 280 review sheet for second midterm exam, April 17, 2001
Exam covers all of chapter 2 except sections 2.3.4
(Huffman codes) and 2.5.3 (symbolic algebra).
sample questions with some answers
-
What is a recognizer? __________
Ans: a predicate that is true just for a specific type. For instance
null? pair? list? procedure? number? sales-employee?
-
What is a constructor? __________
Ans: a procedure for creating a new instance of some object type.
For instance make-rat cons new-cx.
-
What is a proper list? __________
Ans: null or a pair whose cdr is a proper list.
-
What is a generic operator? __________
For ans material first review paragraph one of 2.5, then check out
which procedures/operations are being called generic and why.
The following apply to the lists
L = ((1 2) (3 4)) and M = (5 6 7).
...if you think any of these ans may be wrong, just check in scheme.
Also it is good practice to write box and arrow diagrams for these.
-
(append L M) returns __________.
Ans: ((1 2) (3 4) 5 6 7)
-
(list L M) returns __________.
Ans: (((1 2) (3 4)) (5 6 7))
-
(cons L M) returns __________.
Ans: (((1 2) (3 4)) 5 6 7)
-
(cons (list L (+ 1 3)) (append (list M) M)) returns __________.
Ans: ( (((1 2)(3 4)) 4) (5 6 7) 5 6 7) -- whew!
-
(cdr (car L)) returns __________.
Ans: (2) -- caution, "2" is not correct!
-
(length (list L M L L M)) returns __________.
Ans: 5 -- trick question: because easier than you might think!
-
Write (reverse L), the procedure that returns a list which has the items
of L in it, but in reverse order.
Ans: Reverse is harder than one might think because of the asymmetric
basic access to a list: car is easy, last element is work to get.
It is rather easy to write a wrong solution.
; (reverse L1) ->L2. Assumes L1 is a proper list, returns a list of the
same elements, but in the opposite order.
(define (reverse L)
(define (reverse-iter L1 L2)
(if (null? L1)
L2
(reverse-iter (cdr L1) (cons (car L1) L2)) ))
(reverse-iter L '()) )
-
Write a procedure split which takes a list as argument
and returns a list of length 2. The two items in this output list
are lists. The first one is the list of all the elements of the input
list that are in odd numbered positions. The second list is all the
elements in even numbered positions.
> (split (list 1 2 3 4 5 6 7 8 9 0)) ; input may have even length
---> ((1 3 5 7 9) (2 4 6 8 0))
> (split (list 1 2 3)) ; input may have odd length
---> ((1 3) (2))
> (split (list 1)) ; input may be short
---> ((1) ())
> (split '() ) ; input may be very short
---> (() ())
> (split (list "a" 1 "b" 77 (* 2 4) "c" '(1 2))) ; it doesn't matter what's in the list
---> (("a" "b" 8 (1 2)) (1 77 "c"))
Ans: Here are three solutions representing different approaches to the
problem (my favorite is the second one):
;; Solution 1: do and just use one half of the job.
(define (split L)
; procedure for getting the odd position elements
(define (odds L)
(cond ((null? L) '() )
((null? (cdr L)) (list (car L))) ; ask self: why not just (car L)?
(else (cons (car L) (odds (cddr L))) ) ))
(if (or (null? L) (null? (cdr L)))
(list (odds L) '())
(list (odds L) (odds (cdr L))) ))
;;;;;;;;;;;;;;;;
;; Solution 2: do both halves with procedures that call each other recursively.
(define (split L)
(define (odds L) (if (null? L) '() (cons (car L) (evens (cdr L)))))
(define (evens L) (if (null? L) '() (odds (cdr L))))
(list (odds L) (evens L)) ) ;; short and sweet!
;;;;;;;;;;;;;;;;
;; Solution 3: iterative
(define (split L)
;; procedure to add odd-position elements of L to odd-L,
;; and add even-posn elts of L to even-L.
(define (split-iter L odd-L even-L)
(if (null? L)
(list odd-L) even-L)
(split-iter (cdr L) even-L (cons (car L) odd-L)) ))
(split-iter L '() '()) )
;;;;;;;;;;;;;;;;;;
;; Solution 3a: actually that split-iter is going to return the lists in
;; reverse order. So the last line should be:
(map reverse (split-iter L '() '())) )
Stuff on painters
- Write a painter (named "en") to draw the letter "N" with its vertical
bars ON the side edges of the frame.
;; Ans:
(define en
(define p1 (make-vect 0 0))
(define p2 (make-vect 0 1))
(define p3 (make-vect 1 0))
(define p4 (make-vect 1 1))
(segments->painter (list (make-segment p1 p2)
(make-segment p2 p3)
(make-segment p3 p4) )))
- Write a painter to draw this figure:
Ans: no figure! go figure?
- What does this-painter draw?
(define this-painter (beside (beside en (flip-vert en)) en) )
Ans: Do it in scheme and see!
- Define a procedure (mirror p:Painter) that
produces a painter
that draws p twice, inverted, flip-vert, in the top half and unchanged
in the bottom half of the frame.
;; Ans:
(define (mirror p:Painter)
(lambda (frame)
(below p:Painter (flip-vert (beside p:Painter p:Painter))) ))
- Define a procedure (circus-mirror u:UPO p:Painter) that
produces a painter that draws p twice, once with
u applied to p in the top half, and once, unchanged, in the bottom half
of the frame. (UPO means unary painter operator.)
;; Ans:
(define (circus-mirror upo painter)
(lambda (frame)
(below painter (upo painter))))
- Define a procedure (new-mirror u:UPO) that
produces a UPO so that ((new-mirror u) p) is a painter that draws
the same thing as (circus-mirror u p).
;; Ans:
(define (new-mirror u)
(lambda (p)
(circus-mirror u p) ))
Stuff on sets
- Write an efficient procedure to form the union of two sets of
numbers represented as sorted lists.
;; Ans:
(define union (lambda (s1 s2)
(cond ((null? s1) s2)
((null? s2) s1)
((< (car s1) (car s2)) (cons (car s1) (union (cdr s1) s2)))
((= (car s1) (car s2)) (cons (car s1) (union (cdr s1) (cdr s2))))
((> (car s1) (car s2)) (cons (car s2) (union s1 (cdr s2))))
)))
- What advantages does the sorted tree set representation have
over the sorted list representation? What advantages does the
sorted list representation have over the sorted tree representation?
Ans: when balanced, sorted tree will have faster member-set? and adjoin-set?
but sorted list will have faster union and intersection when the two lists
are about the same length.
- In the following code join-em is a procedure which (like append)
takes two lists and forms the list consisting of all the elements in the first
list followed by all the elements in the second list. What difference
does it make in the number of steps to do tree->list on a tree T with
n nodes if join-em is a one step procedure or is a k step procedure,
where k is the number of items in the first list?
(define (tree->list T)
(if (empty-tree? T)
'()
(join-em (tree->list (left-branch T))
(cons (node-value T)
(tree->list (right-branch T)) )) ))
Ans: join-em is called at every node of the tree so it is called n times
when there are n nodes in the tree. If each use is a one step cost
the total cost is O(n). If each use is the cost of the size of the first,
left, tree, then the cost is the sum of the sizes of all left branch trees,
which at worst can be the sum of all the numbers from 1 to n-1, which
is O(n^2). Remark:
This question is based on material we didn't cover, or at any rate didn't
emphasize so far. We didn't discuss this matter so far this term.
So don't expect it's brother on the exam.
-
Mercy hospital and the VA hospital have decided to use a common system
to support their patient records. Each hospital keeps a record on new
patients consisting of the patient's name, date of admission, and diagnosis.
However, Mercy uses a list of the form (name date diag), whereas
VA uses (diag name date). In each hospital, many programs deal with these
records, so it is not possible to simply change one to conform to the other.
To handle the combined record keeping system, it is necessary to provide
the constructors make-Mercy-record and make-VA-record and provide
the generic selectors name, date, and diag.
Sketch how you might use data-directed programming to do this,
using manifest type and using put and get on a table of procedures.
;; Ans:
(define (install-pkg-Mercy)
(put 'make-Mercy-record 'Mercy (lambda (n dt dg) (attach-tag 'Mercy (list n dt dg))))
(put 'name 'Mercy car)
(put 'date 'Mercy cadr)
(put 'diag 'Mercy caddr)
)
(define (install-pkg-VA)
(put 'make-VA-record 'VA (lambda (n dt dg) (attach-tag 'VA (list n dt dg))))
(put 'name 'VA cadr)
(put 'date 'VA caddr)
(put 'diag 'VA car)
)
(define (make-Mercy-record . args) (apply (get 'make-Mercy-record 'Mercy) args )
(define (name record) (apply-generic 'name record))
;; etc.
Here is a quick summary of some procedures studied and other terminology,
Pairs: car cdr cons pair? null?
Uses of pairs
abstraction barriers - levels from basic scheme up to application functions
Sequences (lists): nth length list append reverse list?
Symbols and quote '
Symbolic differentition: Expressions are naturally processed using tree recursion.
Simplification is an issue that Make-sum, etc can handle.
rational numbers:
interval arithmetic:
List processing:
(map f L) (filter p? L)
More list processing:
(flatten L) (extent L)
Painters: segments->painter,
Painter ops: transform-painter,
unary ops: flip-vert, rotate90, erase, etc.
binary ops: beside, below,
higher order ops: square-of-four,
recursive ops: right-split, corner-split, up-split, square-limit,
Frames: constructors and selectors
Multiple representations,
Manifest type,
Data directed programming
Some good exercises from chapter 2 are: 2.18, 2.21, 2.22, 2.23, 2.24