10진수 숫자를 로마자로 변환하는 문제였다. 구현에 고민을 제법 한 문제였다. 재귀를 쓸 수도 있고 그 외에도 여러 가지 방법을 쓸 수 있었을 것 같다(다 풀고 발견한 것이었지만 이 문제는 재귀를 연습하기 위해 만들어진 듯하다).
이번에 Exercism을 풀면서는 전체적으로 매핑의 가짓수가 늘어나더라도(예를 들어 지금은 천 단위 숫자까지만 변환하면 됐지만 이후 대응해야 하는 수의 크기가 커지는 경우를 생각) 코드 수정 없이 데이터만 수정하면 되도록 해보고 싶어서 데이터 부분을 별도 맵으로 분리해서 코드를 짜 보았다.
defmodule RomanNumerals do
@exp_to_roman_mapping %{
0 => %{1 => "I", 4 => "IV", 5 => "V", 9 => "IX"},
1 => %{1 => "X", 4 => "XL", 5 => "L", 9 => "XC"},
2 => %{1 => "C", 4 => "CD", 5 => "D", 9 => "CM"},
3 => %{1 => "M"},
}
@doc """
Convert the number to a roman number.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(number) do
Integer.digits(number)
|> Enum.reverse()
|> Enum.with_index()
|> Enum.map(&to_roman/1)
|> Enum.reverse()
|> Enum.join("")
end
defp to_roman({digit, exp}) do
case digit do
d when d in [4, 5, 9] -> @exp_to_roman_mapping[exp][d]
d when d > 5 -> @exp_to_roman_mapping[exp][5] <> String.duplicate(@exp_to_roman_mapping[exp][1], d - 5)
d -> String.duplicate(@exp_to_roman_mapping[exp][1], d)
end
end
end
'호두나무 공방 > Exercism in Elixir' 카테고리의 다른 글
Captain's Log - Exercism in Elixir (0) | 2022.06.09 |
---|---|
Rotational Cipher - Exercism in Elixir (0) | 2022.06.08 |
RNA Transcription - Exercism in Elixir (0) | 2022.06.06 |
Raindrops - Exercism in Elixir (0) | 2022.06.03 |
Pig Latin - Exercism in Elixir (0) | 2022.06.02 |