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
factorial
function 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 givenx
andexp
. 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