# Recursion - Wed, Sep 18

## Recursive Functions

A function is recursive if the body of that function calls itself, directly or indirectly.

### Digit Sums

This is useful for typo correction, such as on credit cards. The last digit is the checksum digit.

### The Problem Within the Problem

• The sum of the digits of 6 is 6.
• The sum of the digits of 2019 is the sum of the digits of 201, plus 9.
• The sum of the digits of 201 is the sum of the digits of 20, plus 1.
• The sum of the digits of 20 is the of the digits of 2, plus 0.
• The sum of the digits of 2 is 2.

This is recursion.

``````def split(n):
"""Split positive n into all but its last digit and its last digit."""
return n // 10, n % 10

def sum_digits(n):
"""Return the sum of the digits of positive integer n."""
if n < 10:
return n
else:
all_but_last, last = split(n)
return sum_digits(all_but_last) + last``````

## Iteration vs. Recursion

Iteration is a special case of recursion:

``````def fact_iter(n):
total, k = 1, 1
while k <= n:
total, k = total*k, k+1

The above function is equivalent to the recursive function we wrote before. However, the iterative function runs faster in Python than the recursive function because creating new frames takes a little bit of time. However, other languages process code differently and more efficiently, doing the same thing under the hood for both functions, so the run speed is similar/the same.

The iterative function uses four names: `n, total, k, fact_iter`. The recursive function does the same thing with just two names: `n, fact`.

## Verifying Recursion Using the Recursive Leap of Faith

``````def fact(n):
if n == 0:
return 1
else:
return n * fact(n-1)``````

Is `fact` implemented correctly? 1. Verify the base case 2. Treat `fact` as a functional abstraction 3. Assume that `fact(n-1)` is correct 4. Verify that `fact(n)` is correct

Essentially, assume that `fact` works for simpler instances of the same problem. If it does, you can generalize your conclusion to all uses of `fact`.

## Mutual Recursion Using the Luhn Algorithm

A function `f` calls a function `g` which calls `f` which calls `g` and so on and so forth.

The Luhn Algorithm is used to verify credit card numbers. From Wikipedia:

First: From the rightmost digit, which is the check digit, moving left, double the value of every second digit; if product of this doubling operation is greater than 9 (e.g., 7 * 2 = 14), then sum the digits of the products (e.g., 10: 1 + 0 = 1, 14: 1 + 4 = 5)

Second: Take the sum of all the digits

The Luhn sum of a valid credit card number is a multiple of 10.

``````def luhn_sum(n):
if n < 10:
return n
else:
all_but_last, last = split(n)
return luhn_sum_double(all_but_last) + last

def luhn_sum_double(n):
all_but_last, last = split(n)
luhn_digit = sum_digits(2 * last)
if n < 10:
return luhn_digit
else:
return luhn_sum(all_but_last) + luhn_digit``````

## Converting Iteration to Recursion

Formulaic: Iteration is a special case of recursion. Idea: The state of an iteration can be passed as arguments.