Recursion with lists

Course links

Exercise 1

Develop a Scheme procedure product that takes a list of numbers as its argument and returns the result of multiplying them all together.

Warning: (product '()) should not be 0. It should be the identity for multiplication, just as (sum '()) is the identity for addition. Explain why.

Exercise 2

Develop a Scheme procedure square-each-element that takes a list of numbers as its argument and returns a list of their squares. Here's one sample interaction to get you started; you should, of course, write out a few others.

> (square-each-element (list -7 3 12 0 4/5))
(49 9 144 0 16/25)
Hint: For the base case, consider what the procedure should return when given a null list; for the other case, separate the car and the cdr of the given list and consider how to operate on them so as to construct the desired result.

Exercise 3

Develop a Scheme procedure lengths that takes a list of lists as its argument and returns a list of their lengths. Here is one sample:

> (lengths '((alpha beta gamma)
             (delta)
             ()
             (epsilon zeta eta theta iota kappa)))
(3 1 0 6)

Exercise 4

Develop a Scheme procedure named filter-out-skips that takes a list of symbols as its argument and returns a list that does not contain the symbol skip, but is otherwise identical to the given list. (Use the predicate eq? to test whether two symbols are alike.)

> (filter-out-skips '(hop skip jump skip and skip again))
(hop jump and again)

Begin by writing out a set of sample calls and the intended results. In addition to ``normal'' examples like the one shown above, your samples should include a case in which the given list is empty, a case in which it contains only skips, and one in which it contains only symbols other than skip.

Exercise 5

Develop a Scheme procedure named tally-occurrences that takes two arguments, a symbol and a list of symbols, and determines how many times the given symbol occurs in the given list.

Hint: Use direct recursion. Here are the questions that you must resolve: What is the base case? What value should the procedure return in that case? How can you simplify the problem in order to recursively invoke the procedure being defined? What do you need to do with the value of the recursive procedure call in order to obtain the final result?

Exercise 6

Using the disparity procedure defined in the reading on conditional evaluation, develop a Scheme procedure named gaps that takes a non-empty list of real numbers as its argument and returns a list of the disparities between numbers that are adjacent on the given list. Here is one sample to get you started:

> (gaps '(30 16 21 9 42))
(14 5 12 33)

Note that gaps always returns a list one element shorter than the one it is given.

Exercise 7

Develop a Scheme predicate all-in-range? that takes a list as argument and determines whether all of its elements are in the range from 0 to 100, inclusive.

Exercise 8

Develop a Scheme predicate element? that takes two arguments, a symbol and a list, and determines whether the given symbol is an element of the given list.

The following exercises diverge a little more from the patterns developed in the reading and are intended for students who have finished the preceding exercises early or are bored with them.

Exercise 9

Define and test a Scheme procedure add-pairs that takes an even-length list of numbers as its argument and returns a list of the results of adding the elements of the given list, two at a time.

> (add-pairs '(7 3 6 8 4 2 1 9))
(10 14 6 10)

Exercise 10

Develop a Scheme procedure riffle that takes two lists as arguments and returns a list that results from riffling the given lists together, like two halves of a deck of cards: The first element of the result list should come from the first given list, the second from the second, the third from the first list again, the fourth from the second, and so on. Once the shorter of the given lists is exhausted, all the rest of the elements of the result list should come from the other list.

> (riffle '(a b c d e) '(x y z))
(a x b y c z d e)
Hint: Separate off two ``base cases,'' one for each list.

Exercise 11

Define and test a Scheme procedure unriffle that takes a list as argument and returns a list of two lists, one comprising the elements in even-numbered positions in the given list, the other comprising the elements in odd-numbered-positions.

> (unriffle '(a b c d e f g h i))
((a c e g i) (b d f h))
Hint: Define a separate ``helper'' procedure that takes the car of the given list and the result of the recursive call as its arguments and rearranges the pieces as necessary to obtain the final result.