CS 111: More Recursion

Table of Contents

  1. Trees
  2. Random Trees
  3. Exercise 1: countBranches
  4. Exercise 2: zigzag
  5. Exercise 3: Koch curves and snowflakes
  6. Recursion with lists
  7. Exercise 4: countDownListPrintResults
  8. Exercise 5: countUpList
  9. Fibonacci Numbers
  10. Exercise 6: fibRec
  11. Exercise 7: fibLoop

1. Trees

Once again we will use turtle graphics to solve interesting recursion problems. First import the turtle module.

Last time we look at invariance in the context of turtle spirals. Now we will use the idea of invariant functions to create more sophisticated turtle designs,
again using recursion. The slides show some designs created with the trees recursive function.

Let's try the tree from the slides:

Let's create a more sophisticated tree, the one that is in the cover page of the slides:

2. Random Trees

The function tree creates symmetric, perfect trees that don't resemble natural trees.
Can we do better? Yes, by introducing randomness.

Run the code below and then study how it works.

3. Exercise 1: Fruitful Trees (puns abound...)

Let's apply our concepts of invariance, trees, and fruitful recursion into one example. Using our function tree from above draw the same tree but also return a count of all the branches drawn.

4. Exercise 2: Modify the zigzag function to become invariant

This is another exercise to help work on the concept of invariance. First run the code to see what it does, and then modify it so that the turtle returns to the center, where it started.

5. Exercise 3: Koch curves and snowflakes

Define the koch and snowflake functions as indicated on the slides.

HINT: This function does work in its base case. It also calls itself several times in the recursive case.

Once you write the function koch, writing snowflake is really simple.
This is because snowflake is not a recursive function. It simply calls the function koch that is recursive.

6. Recursion with lists

We have seen recursion in the context of printing and adding numbers with countUp and sumUp, respectively. Here is a function that creates a list of numbers from n to 1.

7. Exercise 4: countDownListPrintResults

Modify countDownList to be the function countDownListPrintResults that prints out the list returned by each recursive call. For example:

In[]: countDownListPrintResults(5)
[]
[1]
[2, 1]
[3, 2, 1]
[4, 3, 2, 1]
[5, 4, 3, 2, 1]
Out[]:
[5, 4, 3, 2, 1]

8. Exercise 5: countUpList

Write a new function countUpList, which returns a list of integers from 1 up to n.
You will only need to change one thing in countDownList to get countUpList.

9. Fibonacci Numbers

Fibonacci numbers model the number of pairs of rabbits in a given month, assuming:

  1. rabbits never die;
  2. sexually mature rabbits produce a new rabbit pair every month; and
  3. rabbits become sexually mature after one month.

This leads to the following recursive formula for the nth Fibonacci number fib(n):

fib(0) = 0 ; no pairs initially
fib(1) = 1 ; 1 pair introduced the first month
fib(n) = fib(n-1) ; pairs never die, so live to next month
         + fib(n-2) ; all sexually mature pairs produce a pair each month

10. Exercise 6: fibRec

Write the function fibRec that will calculate the nth Fibonacci number recursively.

10.1 Inefficiency of Fibonacci recursion

How long does it take to calculate fibRec(n)? Let's look at the time (in seconds) to calculate some values.

What's the ratio of the time for fib(n+5) to fib(n) for the above examples?

Based on the above, estimate how long it will take to calculate fibRec(100). (Note that there are about 3 x 10^7 seconds in a year.)
The answer is approximately 4.3 million years.

11. Exercise 7: fibLoop

Here is an iterative way to view Fibonacci numbers: the Fibonacci sequence starts with 0 and 1, and each successive number is the sum of the previous two:

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...

The nth Fibonacci number is the value corresponding at the nth index. So fib(0) is 0, fib(1) is 1, fib(2) is 1, fib(3) is 2, etc.

Based on this perspective, Fibonacci numbers can be calculated efficiently via a loop!