Quiz 2
Instructions
- The quiz consists of five questions.
- Read all the questions thoroughly before you begin. It is worth your time to plan ahead!
- The quiz is worth 60 points. Each question is worth twelve points.
- Partial credit will be given where possible, so show your work.
- The quiz lasts forty (40) minutes. It is due at 1:45 PM.
Because the primary goal of this portion of the course is to
demonstrate the ability to write recursive programs, you
may not use any built-in function that does
the recursion for you, such as map,
filter, reverse, or
string->list.
Problem 1
Write a structurally recursive function
(drop-last los)
that takes one argument, a list of symbols los:
<list-of-symbols> ::= ()
| (<symbol> . <list-of-symbols>)
drop-last returns a list of all the symbols in
los except the last one. For example:
> (drop-last '(a b c d)) '(a b c) > (drop-last '(x)) '()
If los is the empty list, drop-last
returns the empty list.
Problem 2
Write a structurally recursive function
(tree-count test? tree)
that takes two arguments: a boolean function test?
and a binary tree tree of this form:.
<binary-tree> ::= <number>
| (<number> <binary-tree> <binary-tree>)
tree-count returns the number of values in the tree
that satisfy test?, a one-argument function. For
example:
> (tree-count positive? '(1 (2 3 4) 5)) ; all five are positive
5
> (tree-count (lambda (n) (> n 10)) ; nodes greater than 10
'(8 (13 11 (5 24 6)) (15 (12 10 14) 20)))
7
Note: tree-count does not need an
extra parameter to solve this problem! Use regular structural
recursion.
Problem 3
Write a mutually recursive function
(slist-contains? s slst) that takes two arguments,
a symbol s and an s-list slst:
<s-list> ::= ()
| (<symbol-expression> . <s-list>)
<symbol-expression> ::= <symbol>
| <s-list>
slist-contains? returns true if s
appears anywhere in slst, and false otherwise.
For example:
> (slist-contains? 'eugene '((a b) (((b g r) (f r)) c (d e)) b)) #f > (slist-contains? '/ '(if (zero? n) zero (/ total n))) #t
slist-contains? must be mutually recursive
with the function symexp-contains?, which determines
if a symbol appears anywhere in a symbol expression.
Problem 4
Write brief answers for each of the following items. One phrase, sentence, or Racket expression is sufficient for each.
- How does program derivation improve the efficiency of a mutually recursive solution?
-
This version of the
factorialfunction is tail recursive:(define (factorial n acc) (if (zero? n) acc (factorial (sub1 n) (* n acc))))What does that statement mean, in terms of the way the function executes at run time? - In what situations do we need to define an interface procedure to our structurally recursive function?
-
The expression
(occurs-free? x exp)is not always equal to the expression(not (occurs-bound? x exp))for a givenxandexp. Give an expression in the little language that illustrates why.
Extra Credit. There are two ways in which this is true. Give distinct examples that illustrate both ways.
Problem 5
Write a structurally recursive function
(contains-varref? v exp) that takes two arguments:
v, a symbol, and exp, an expression in
our little language:
<exp> ::= <varref>
| (lambda (<var>) <exp>)
| (<exp> <exp>)
contains-varref? returns true if v is
used as a variable reference anywhere in exp, and
false otherwise. For example:
> (contains-varref? 'y 'y)
#t
> (contains-varref? 'x '(lambda (x) x))
#t
> (contains-varref? 'y '(lambda (y) x))
#f
> (contains-varref? 'x '(f (lambda (y) x)))
#t
> (contains-varref? 'x '( (lambda (x) y) ; x is not used here
(lambda (y) x) )) ; but x is used here
#t
You must use these syntax procedures for the little language, as provided in class.
exp? varref? lambda? app?
lambda->param app->proc
lambda->body app->arg