Midterm 1

Recursion

Recursion Problems

First, let's try writing count. We already know the plan, which is to count the first word and then count the rest. We start with the easy part:

(define (count sent)
What next? Well, I always start recursion by figuring out how I stop. This is the base case. What's the simplest possible sentence to count? That would be the empty sentence.
(define (count sent)
  (if (empty? sent)
      0
Now let's do a little bit of work. What would that be? How about counting the first word? That gives us 1. Then we do the rest of the work, which is (count (bf sent)). In other words, we count everything after the first word of the sentence. Finally, we combine the 1 for the first word and the (count (bf sent)) for all the other words. How? We add them together:
(define (count sent)
  (if (empty? sent)
      0
      (+ 1 (count (bf sent)))))
Do you believe this works? Why should you? Let's test it out.
  1. We start with (count '(I love cs3)). The sentence isn't empty, so we do (+ 1 (count (bf sent))).
  2. Now we have (+ 1 (count '(love cs3))). We can't do the + until we figure out the underlined part, though.
  3. Now we do the underlined part. Since the sentence isn't empty, we do the (+ 1 (count (bf sent))) line again. That leads us to (+ 1 (+ 1 (count '(cs3)))).
  4. We do the underlined part again. Since the sentence isn't empty, we do the (+ 1 (count (bf sent))) line again. That leads us to (+ 1 (+ 1 (+ 1 (count '())))).
  5. Since the sentence is empty, (count '()) gives us 0. Now we have (+ 1 (+ 1 (+ 1 0))), which gives us 3.

Now let's try writing a procedure that takes a sentence of numbers and returns the first even number. Let's call it find-even. How do we start? With the base case, of course. What is the base case? Well, what's the simplest possible sentence? Hmm... I'm not quite sure what that means. Another way to think about the base case is, "Can I look at my sentence and give you the answer with almost no work?" Well, if the first word in the sentence is even, I can tell you the answer right away.

(define (find-even sent)
  (if (even? (first sent))
      (first sent)
Okay, so if we don't find the first even number right away, we have to look through the rest of the sentence. The rest of the sentence is (bf sent) and we look through it with find-even, so we get
(define (find-even sent)
  (if (even? (first sent))
      (first sent)
      (find-even (bf sent)))) 
How well does this work?
  1. We start with (find-even '(1 3 5 6 7 8)). The first number isn't even, so we throw it away and keep looking.
  2. Now we have (find-even '(3 5 6 7 8)). The first number isn't even, so we throw it away and keep looking.
  3. Now we have (find-even '(5 6 7 8)). The first number isn't even, so we throw it away and keep looking.
  4. Now we have (find-even '(6 7 8)). The first number is even, so we stop and return it.
Now let's try to identify all four parts of this recursive problem. The base case is easy. We already did that. What about "Do a little bit of work?" Personally, I'd say that checking to see if the first word is even is doing a little bit of work. In this case, it also happens to be the base case. That's fine. What about "Do all the rest of the work?" That's (find-even (bf sent)). Finally, what about "Combine the little bit of work with all the rest of the work?" Hmm... I don't see that one. Why? Well, we aren't building something. We're looking for something. That means we don't really have anything to combine (build).

Now let's try returning all of the even numbers in a sentence. This is very different from finding the first number. Instead of looking for one number, we are building a sentence. Let's call this procedure all-evens. Once again, we start with the base case. Can we think of the simplest sentence that we could possibly give all-evens? What about the empty sentence? There aren't any numbers in it.

(define (all-evens sent)
  (cond (empty? sent) 0)
Now we need to see if we've found an even number. We could do that with (even? (first sent)).
(define (all-evens sent)
  (cond ((empty? sent) 0)
        ((even? (first sent))
What do we do if we actually find an even number? We need to put it into a sentence.
(define (all-evens sent)
  (cond ((empty? sent) 0)
        ((even? (first sent))
         (se (first sent)
What else should we put in the sentence? All of the other even numbers, of course! How do we find them? That's what all-evens is for.
(define (all-evens sent)
  (cond ((empty? sent) 0)
        ((even? (first sent))
         (se (first sent) (all-evens (bf sent))))
So if the sentence isn't empty and the first word isn't even, the first word must be odd. What do we do in this case? Well, we don't put the first word in the sentence. We just go on and look for some even words.
(define (all-evens sent)
  (cond ((empty? sent) 0)
        ((even? (first sent))
         (se (first sent) (all-evens (bf sent))))
        (else (all-evens (bf sent)))))