A recursive algorithm for incrementing natural numbers
Incrementing a natural number is simple as adding to it, so why would we ever want to think about a fancy way of doing it? All we need to do is to go from to , and well, that's pretty obvious.
But, let's take a look at one example:
from math import floor
def increment(y):
if y == 0:
return 1
elif y % 2 == 1:
return 2 * increment(floor(y / 2))
return y + 1
from math import floor
def increment(y):
if y == 0:
return 1
elif y % 2 == 1:
return 2 * increment(floor(y / 2))
return y + 1
It's a beautiful recursive algorithm for incrementing natural numbers, taken from Steven Skiena’s The Algorithm Design Manual.
But how do we know that it's correct?
The book answers it, by using induction.
The base case is when equals , and if that's the case, we return . That is correct: .
Our induction hypothesis is that is . We assume that is the case, and go on to show that holds as well, that is, .
When is an even number (when ), we return in the last line, so that's correct.
So what's the deal with odd numbers, then?
When is odd (when ), what is returned from the increment
function is:
2 * increment(floor(y / 2))
2 * increment(floor(y / 2))
Remember that we need to prove , so we need to prove that what we return here is indeed y + 1
.
When is odd, we can write it as , for some integer . In that case, what we have is:
2 * increment(floor(((2 * m) + 1) / 2))
2 * increment(floor(((2 * m) + 1) / 2))
Or:
We can simplify it by dividing the terms inside by :
Taking the floor of , we have just (remember that is an integer):
...which is (by our induction hypothesis):
...which is:
We said that is . And the result of our increment function returns , which is the correct answer: 🎉
This is certainly a bit tricky at first, but it provides an important lesson that induction is a solid way of proving correctness, even though most of it feels like magic.
The lectures based on the book The Algorithm Design Manual can be found here.