## Practice Problems 9 Solution

1. Write the docstring for the following recursive function:

 def mystery(a_list):
"""
Check if list is sorted in ascending order

Args:
a_list: A list of comparable values

Returns:
True if listed is sorted in ascending order
"""
if len(a_list) <= 1:
return True
else:
return (a_list[0] <= a_list[1]) and mystery(a_list[1:])


Try to describe the recursive relationship in a single sentence.

“A list is in sorted order if the first element is less than or equal to the second element and sublist starting with the second element is in sorted order.”

2. Write a recursive function named rec_min that takes a non-empty list as a parameter and returns the minimum value in the list. You must implement this recursively (no loops!) and should not use the min function.
 def rec_min(a_list):
""" Return the minimum value of a_list using a recursive algorithm """
if len(a_list) == 1:
return a_list[0]
else:
curr = a_list[0]
rest = rec_min(a_list[1:])
if rest < curr:
return rest
else:
return curr

3. Write a function named rec_in that takes two parameters, a list and an item, and returns True if that item is in the list, and False otherwise. You must implement this recursively (no loops!) and should not use functions like index, count, or in.

 def rec_in(a_list, item)
""" Return True if item is contained in a_list, False otherwise """
if len(a_list) == 0:
return False
else:
if a_list[0] == item:
return True
else:
return rec_in(a_list[1:], item)


A more concise solution (taking advantage of short circuit evaluation of logical expressions):

 def rec_in(a_list, item):
""" Return True if item is contained in a_list, False otherwise """
if len(a_list) == 0:
return False
else:
return a_list[0] == item or rec_in(a_list[1:], item)

4. The Fibonacci numbers are the following:

1, 1, 2, 3, 5, 8, 13, 21, ...


The nth Fibonacci number is defined as the sum of the previous two Fibonacci numbers (and the first two numbers are both 1). So, the 3rd Fibonacci number is 2, the 4th Fibonacci number is 3, etc.

Write a function named fib that takes a number n as a parameter and returns the nth Fibonacci number. Your function must be a recursive function.

def fib(n):
""" Calculates the nth Fibonacci number recursively """
if (n == 1) or (n == 2):
return 1
else:
return fib(n-1) + fib(n-2)

5. Using the fib function above, the call stack would look like

 fib(4)
fib(3)
fib(2)
fib(1)
fib(2)


and thus the arguments would be 4, 3, 2, 1, 2.

6. Your recursive fib function calculates the correct answer, but isn’t efficient. Try calling your function to calculate the 100th Fibonacci number. Why is your recursive implementation so slow?

The call stack for fib(5):

 fib(5)
fib(4)
fib(3)
fib(2)
fib(1)
fib(2)
fib(3)
fib(2)
fib(1)


fib would be called 9 times. The function is slow because it is performing the same computation over and over again. For example fib(n) invokes fib(n-1) and fib(n-2) and fib(n-1) also invokes fib(n-2) and fib(n-3) (and so on…). We are more than doubling the amount the computation each time we double n, and in fact the recursive solution has exponential time complexity.

7. The program will draw a partial star (6 arms total) with a dot in the center with smaller and smaller arms as they approach the vertical, that is the horizontal line as a total length of 40, the 45 degree arm has a length 20, the vertical arm has a length of 10. Execute the code to see the complete shape.

8. The code will print:

 8
4
2
2
4
2
2