Hey!

Welcome back to another episode of exercism.io exercise wherein we practice our logic and problem solving capabilities.

Okay! so I got this new challenge called `Converting a number into a Roman Numeral`

.

It says there that it is easy, but as for me it wasn't hahaha!

### Start to Analyze!

As for me, the key hints to solve the problem is by the power of `algorithm`

and `pattern matching`

! Hooray 🔥

Honestly I struggled a lot on juggling different ideas on how to solve this problem. So first I started to gather some information that can be useful for me.

### Solution

```
@doc """
Convert the number to a roman numeral.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(number) do
end
```

Given the function doc and spec, I started to think that I need to;

`convert integer to string`

`split and turn them into an array`

```
@doc """
Convert the number to a roman numeral.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(number) do
numbers =
number
|> Integer.to_string()
|> String.split("", trim: true)
end
```

In this way, I thought I could manipulate them one by one and match the corresponding values according to their place number. So to satisfy it;

- using
`Enum.with_index()`

I jump into the data and transform them into arrays elements together with their indexes.

```
@doc """
Convert the number to a roman numeral.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(number) do
numbers =
number
|> Integer.to_string()
|> String.split("", trim: true)
|> Enum.with_index()
end
```

Now the next thing that I did was to `transform the data into a map`

because I thought in this was I could pattern match depending on their
index as their place number

```
@doc """
Convert the number to a roman numeral.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(number) do
numbers =
number
|> Integer.to_string()
|> String.split("", trim: true)
|> Enum.with_index()
|> Enum.map(fn {x, index} ->
{index, String.to_integer(x)}
end)
|> Map.new()
end
```

Finally, I created a private function named `to_numeral/1`

that accepts a map.

```
@doc """
Convert the number to a roman numeral.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(number) do
numbers =
number
|> Integer.to_string()
|> String.split("", trim: true)
|> Enum.with_index()
|> Enum.map(fn {x, index} ->
{index, String.to_integer(x)}
end)
|> Map.new()
|> to_numeral
end
```

### WTF is `to_numeral/1`

been doing? 🤔

So the next plan that I have is to create a new private function that will turn this `Map`

into `Roman Numeral`

values.

```
defp to_numeral(%{0 => thousands, 1 => hundreds, 2 => tens, 3 => ones}) do
parse(thousands, :thousands) <> to_numeral(%{0 => hundreds, 1 => tens, 2 => ones})
end
defp to_numeral(%{0 => hundreds, 1 => tens, 2 => ones}) do
parse(hundreds, :hundreds) <> to_numeral(%{0 => tens, 1 => ones})
end
defp to_numeral(%{0 => tens, 1 => ones}) do
parse(tens, :tens) <> to_numeral(%{0 => ones})
end
defp to_numeral(%{0 => ones}) do
parse(ones, :one)
end
```

Yeah I know! there are so many movings parts here. It kind a hard to admit that I did all of this but life isn't always perfect. I need to be dumb sometimes for me to learn. So you know how this ends.

I created a private function `parse/2`

that turns this numbers according to their equivalent value in
roman characters.

So in all, I've created about `90+`

line of code just to deliver my answer. For the next blog, my goal is to refactor this one and come up with
a much better approach and apply it to my future problem solving at exercism: track elixir.

You can check out my solution here