Quiz 2

Instructions

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.

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