Optimizing code with algebra
Tags: coding, math, optimization, python
Published: 2018-09-30 03:38:06

---
title: Optimizing code with algebra
published: true
description: A little insight on how math makes us better developers
tags: coding, math, optimization, python
---

![Photo by Roman Mager on Unsplash](https://thepracticaldev.s3.amazonaws.com/i/c24nlacbohaiz8vrwngt.jpg)
###### Photo by Roman Mager on Unsplash

During a semester in college I took a subject called "Discrete Mathematics". The lecturer decided to split the class in groups. Each group consisted of 2 or 3 students. They were meant to do expositions about a particular subject assigned by the lecturer.

In the group I was on (we were only two, actually), we were assigned with the subject of *recurrency relations*. [According to Wikipedia](https://en.wikipedia.org/wiki/Recurrence_relation), this is:

> _an equation that recursively defines a sequence or multidimensional array of values, once one or more initial terms are given: each further term of the sequence or array is defined as a function of the preceding terms._

In other words, a *recursive function* ;)

A perfect situation to explain this concept with code :D

## Hanoi Towers

Do you remember this toy?

![haoni-towers](https://thepracticaldev.s3.amazonaws.com/i/t3dh0kcy1au86mi86eev.jpg)

The famous Hanoi Towers. The game consists of moving every disk from the first pole to the last one (from left to right or viceversa) in the least amount of steps possible. The rules are that a bigger disk cannot be over a smaller one and you can move only one disk at the time. Something like this:

![hanoi-demo](https://thepracticaldev.s3.amazonaws.com/i/mq04i1fxf3thuw4horhc.gif)


This problem has an algorithm that solves it, it goes like this:
![hanoi-formula](https://thepracticaldev.s3.amazonaws.com/i/jirw4nz2rll5eua3uyxz.png)

Where _n_ is the amount of disks in the problem.

## Let's code that

Let's use Python to write that algorithm. It's something like this:

```python
def hanoi(n):
    if n <= 1: return 1
    else: return 2 * hanoi(n-1) + 1
```

So if we have 4 disks...

```python
>>> hanoi(4)
15
```

Good. It works. Let's give it a few tries

```python
>>> hanoi(5)
31
>>> hanoi(10)
1023
>>> hanoi(40)
1099511627775
```

Looks pretty good. Now I know how many moves it will take me if I'm using 40 disks (btw, this is gonna take you 10460 years, never try this at home). But what if I have 7000?

```python
>>> hanoi(7000)
Traceback (most recent call last):which
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in hanoi
  File "<stdin>", line 3, in hanoi
  File "<stdin>", line 3, in hanoi
  [Previous line repeated 994 more times]
  File "<stdin>", line 2, in hanoi
RecursionError: maximum recursion depth exceeded in comparison
```

Oh... It seems this is not performant enough. Of course you could "solve" this just increasing the maximum recursion depth in Python (with `sys.setrecursionlimit(n)`), but it's a much better idea to optimize this.

## Optimizing

There are several ways to solve recurrence relations, one of them is _iteration_. It consists of solving the operation step by step and deducting the non-recursive equation from the process. First we try to solve a given value:

![hanoi-algorithm-step-by-step](https://thepracticaldev.s3.amazonaws.com/i/1tu014vif32swkw3mrjp.jpg)

Then, from the last line, we can deduce an equivalent equation:

![hanoi-solved](https://thepracticaldev.s3.amazonaws.com/i/fsqr8515gwqcvpfaht5y.jpg)

If you notice, `t(4) = 8 + 7` is the same as `t(4) = 2^(4-1) + (2^(4-1) - 1)`, that's why it's our initial statement. But now we have solved the recurrence relation, let's use that in our code.

```python
def better_hanoi(n):
    return 2**n - 1
```

And then...

![better_code](https://thepracticaldev.s3.amazonaws.com/i/ntdygfkkefqgrl8zxdj6.jpg)

Now we know how many steps will take to solve it with 7000 disks (probably the lifetime of the universe, several times).

## Conclusion

We have optimized a small algorithm with concepts of discrete mathematics, this is just to give a little insight on how we can benefit of such simple concepts to build better programs.