Photo by Julian Dufort on Unsplash

Russian Peasant Multiplication — with Elixir — Part 3

Houman Kargaran
2 min readMar 29, 2020

If you have followed Part 1 and Part 2 you would know that we have decrement and increment are ready to go.

In this article we will be using higher order function to combine these two together.

A quick recap

In decrement, we reduce the first number to be 1 or zero.
In the increment module we used the number of decrement steps and incremented the second number by doubling each number.

So now we have two lists of numbers.
Next we need to combine these 2 lists together and prepare it for the next step. (Transforming the data and keep it as pure as we can)

We want to end up with something like this:

iex> alias RussianPeasantMultiplication.Combine
RussianPeasantMultiplication.Combine
iex> list1 = [13, 6, 3, 1]
iex> list2 = [238, 476, 952, 1904]
iex> result = Combine.combine(list1, list2) |> unwrap!(result)
[{13, 238}, {6, 476}, {3, 952}, {1, 1904}]

Usage of tuple is intentional here. Since we know exactly the number of elements in our list we can use tuple for a better optimised memory allocation.

Memory usage in tuple is very predictable which make a prefect sense in this example.

Also as usual we are using Monad.Result struct to look after our data structure

Test

as you can see I only tested the happy path.
For a commercial grade application you should use property testing in this case as it makes more sense and it will keep your sanity intact.

Code

As usual we have recursion. (Surprise!!)

line 34 We have used higher order function.
When a function passed into another function and it can be executed in the new function, we call it Higher order function.

We are using this method to keep all the calculations and messy things confined in a function. You have been using it whenever you use Enum.map or any Enum that you pass another function into it.

Technical debt

So far we have one technical debt. It is where we are accepting numbers instead of Monad struct and we are returning a Monad struct. This means we have to unwrap!/1 each result to feed into another function. (Ewww)

New debt!

In the module at line 34 and line 40 . We can easily refactor this.

Although, it make sense to DRY our code, I might be changing this in the next module so I left it alone for now.

line 45 We are making our own concat version. You can use Enum though. (if you don’t have a sense of adventure then use Enum :)

This should do it for now.

In the next article I will go through Filtering and we use the Higher order function combined with conditions.

Happy coding!

--

--