University of California, Berkeley
EECS Department - Computer Science Division

CS3L OaW Lecture 7 : Embedded, Tail, and Advanced Recursion

Thanks to Oliver Grillmeyer and Brendan Ferguson for many of the ideas for these notes


Tail Recursion vs. Embedded Recursion

Short example : sum-0-to-n

;; sum-0-to-n

(define (sum-0-to-n n)
  (if (zero? n)
      0
      (+ n (sum-0-to-n (- n 1)))))
: (model (sum-0-to-n 3))
(+ 3 (sum-0-to-n 2))
(+ 3 (+ 2 (sum-0-to-n 1)))
(+ 3 (+ 2 (+ 1 (sum-0-to-n 0)))) ;; base case
(+ 3 (+ 2 (+ 1 0)))              ;; now going back up, "cleaning up"
(+ 3 (+ 2 1))
(+ 3 3)
6

This is called embedded recursion.

(it's also called linear recursion, because it only uses one recursive call in the recursive case)

Let's rethink the problem : sum-0-to-n-tail

This is called tail recursion, or iteration.

Often it is easier to solve a recursive problem using tail recursion!
...some find this the more intuitive approach.

;; sum-0-to-n-tail
;;
;; INPUTS       : A single number, n
;; REQUIRES     : The number be a positive integer
;; SIDE-EFFECTS : None
;; RETURNS      : The sum of all the integers from 0 to n.
;; EXAMPLE      : (sum-0-to-n-tail 3) ==> 6 ;; 0 + 1 + 2 + 3 = 6

: (define (sum-0-to-n-tail n)
==>

: (define (sum-0-to-n-tail-helper n sum-so-far)
==>
==>
==>
: (model (sum-0-to-n-tail 3))
(sum-0-to-n-tail-helper 3 0)
(sum-0-to-n-tail-helper 2 3)
(sum-0-to-n-tail-helper 1 5)
(sum-0-to-n-tail-helper 0 6) ;; base case
6                            ;; ...done! No need to "clean up"

Another example: my-count vs. my-count-tail

(define (my-count s)
  (if (empty? s)
       0
      (+ 1 (my-count (bf s)))))
: (model (my-count '(a b c)))
(+ 1 (my-count '(b c)))
(+ 1 (+ 1 (my-count '(c))))
(+ 1 (+ 1 (+ 1 (my-count '()))))  ;; base case
(+ 1 (+ 1 (+ 1 0)))               ;; cleaning up
(+ 1 (+ 1 1))
(+ 1 2)
3
: (define (my-count-tail s)
==>

: (define (mct-helper s count-so-far) ;; shortened name for convenience
==>
==>
==>
: (model (my-count-tail '(a b c)))
(mct-helper '(a b c) 0)
(mct-helper '(b c) 1)
(mct-helper '(c) 2)
(mct-helper '() 3)     ;; base case, no clean up needed!
3

More examples: count-even-and-odds

;; count-even-and-odds
;;
;; INPUTS       : A sentence of integers, s
;; REQUIRES     : The sentence consist only of integers
;; SIDE-EFFECTS : None
;; RETURNS      : A two-word sentence, wherein the first word
;;              : is the number of even numbers in the sentence, and
;;              : the second word is the number of odd numbers
;; EXAMPLE      : (count-even-and-odds '(1 2 3 0 -4 8 5)) ==> (4 3)
;;              : (count-even-and-odds '(7 9 5 795)) ==> (0 4)
;;              : (count-even-and-odds '(2 4 999998)) ==> (3 0)
;;              : (count-even-and-odds '()) ==> (0 0)

: (define (count-even-and-odds s)
==>

: (define (ceao-helper
==>
==>
==>
==>
==>

More examples: all-increasing?

;; all-increasing?
;;
;; INPUTS       : A sentence, s
;; REQUIRES     : The sentence consist only of integers,
;;              : AND the sentence be non-empty
;; SIDE-EFFECTS : None
;; RETURNS      : #t if the sentence is in strictly increasing order, else #f
;; EXAMPLE      : (all-increasing? '(-50 1 2 3 5)) ==> #t
;;              : (all-increasing? '(1 2 3 0)) ==> #f

: (define (all-increasing? s)
==>

: (define (ai-helper?
==>
==>
==>
==>

More examples: longest-win-streak

;; longest-win-streak
;;
;; INPUTS       : A sentence of w's and l's, s
;; REQUIRES     : The sentence consist only of w's and l's
;;              : AND the sentence be non-empty
;; SIDE-EFFECTS : None
;; RETURNS      : The count of the team's longest winning streak
;; EXAMPLE      : (longest-win-streak '(l l l l)) ==> 0
;;              : (longest-win-streak '(l w w w l w w l l l l w)) ==> 3

: (define (longest-win-streak s)
==>

: (define (lws-helper
==>
==>
==>
==>

Advanced Recursion

Pascal's triangle : pascal

columns (C)

r
o
w
s

(R)
0 1 2 3 4 5 ...
0

1

         

...

1

1

1

       

...

2

1

2

1

     

...

3

1

3

3

1

   

...

4

1

4

6

4

1

 

...

5

1

5

10

10

5

1

...

... 

...

..

...

...

...

...

...


Pascal's Triangle

pascal(C,R) = pascal(C-1,R-1) + pascal(C,R-1)

(define (pascal C R)
==>
==>
==>
pascal(C,R) = R! / ((R-C)! C!)

Pair all prefixes with suffixes : pair-all

(pair-all '(a b c d) '(1 2 3))
;; ==> (a1 a2 a3 b1 b2 b3 c1 c2 c3 d1 d2 d3)

(pair-all '(to re on) '(ad ward ly))
;; ==> (toad toward toly read reward rely onad onward only)
(define (append-prefix prefix suffixes)
==>
==>
==>

(define (pair-all prefixes suffixes)
==>
==>
==>
==>
==>
==>
==>

Overview of recursion types


Summary

In Lab this week you'll see...

In Life this week you'll see...