diff --git a/elixir/roman-numerals/lib/roman_numerals.ex b/elixir/roman-numerals/lib/roman_numerals.ex index 6914d61..a80978a 100644 --- a/elixir/roman-numerals/lib/roman_numerals.ex +++ b/elixir/roman-numerals/lib/roman_numerals.ex @@ -1,8 +1,49 @@ defmodule RomanNumerals do + @letters [ + %{:unitary => "I", :halfway => "V", :next => "X"}, + %{:unitary => "X", :halfway => "L", :next => "C"}, + %{:unitary => "C", :halfway => "D", :next => "M"}, + %{:unitary => "M", :halfway => "" , :next => ""} + ] + @doc """ Convert the number to a roman number. """ @spec numeral(pos_integer) :: String.t() def numeral(number) do + numeral(number, @letters) + end + + defp numeral(0, _letters) do + "" + end + + defp numeral(number, [current | next]) do + next_iteration = Integer.floor_div(number, 10) + lower_part = number - (next_iteration * 10) + numeral(next_iteration, next) <> letter(lower_part, current) + end + + defp letter(single_value, map) do + case single_value do + 0 -> "" + 1 -> String.duplicate(map[:unitary], 1) + 2 -> String.duplicate(map[:unitary], 2) + 3 -> String.duplicate(map[:unitary], 3) + 4 -> map[:unitary] <> map[:halfway] + 5 -> map[:halfway] + 6 -> map[:halfway] <> String.duplicate(map[:unitary], 1) + 7 -> map[:halfway] <> String.duplicate(map[:unitary], 2) + 8 -> map[:halfway] <> String.duplicate(map[:unitary], 3) + 9 -> map[:unitary] <> map[:next] + + # OR... + # x when x == 0 -> "" + # x when x >= 1 and x <= 3 -> String.duplicate(map[:unitary], x) + # x when x == 4 -> map[:unitary] <> map[:halfway] + # x when x == 5 -> map[:halfway] + # x when x > 5 and x <= 8 -> map[:halfway] <> String.duplicate(map[:unitary], x - 5) + # _ -> map[:unitary] <> map[:next] + end end end diff --git a/elixir/roman-numerals/test/roman_numerals_test.exs b/elixir/roman-numerals/test/roman_numerals_test.exs index d77cf6c..3ba8932 100644 --- a/elixir/roman-numerals/test/roman_numerals_test.exs +++ b/elixir/roman-numerals/test/roman_numerals_test.exs @@ -1,92 +1,78 @@ defmodule RomanNumeralsTest do use ExUnit.Case - # @tag :pending test "1" do assert RomanNumerals.numeral(1) == "I" end - @tag :pending test "2" do assert RomanNumerals.numeral(2) == "II" end - @tag :pending test "3" do assert RomanNumerals.numeral(3) == "III" end - @tag :pending test "4" do assert RomanNumerals.numeral(4) == "IV" end - @tag :pending test "5" do assert RomanNumerals.numeral(5) == "V" end - @tag :pending test "6" do assert RomanNumerals.numeral(6) == "VI" end - @tag :pending + test "7" do + assert RomanNumerals.numeral(7) == "VII" + end + test "9" do assert RomanNumerals.numeral(9) == "IX" end - @tag :pending test "27" do assert RomanNumerals.numeral(27) == "XXVII" end - @tag :pending test "48" do assert RomanNumerals.numeral(48) == "XLVIII" end - @tag :pending test "59" do assert RomanNumerals.numeral(59) == "LIX" end - @tag :pending test "93" do assert RomanNumerals.numeral(93) == "XCIII" end - @tag :pending test "141" do assert RomanNumerals.numeral(141) == "CXLI" end - @tag :pending test "163" do assert RomanNumerals.numeral(163) == "CLXIII" end - @tag :pending test "402" do assert RomanNumerals.numeral(402) == "CDII" end - @tag :pending test "575" do assert RomanNumerals.numeral(575) == "DLXXV" end - @tag :pending test "911" do assert RomanNumerals.numeral(911) == "CMXI" end - @tag :pending test "1024" do assert RomanNumerals.numeral(1024) == "MXXIV" end - @tag :pending test "3000" do assert RomanNumerals.numeral(3000) == "MMM" end