Russian Peasant Multiplication — with Elixir — Part 3
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!