Last active
August 29, 2015 14:24
-
-
Save mutablestate/1bfcfd17d41d4bbf73a1 to your computer and use it in GitHub Desktop.
My current Roman numeral exercism.io iteration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Roman do | |
@arabic_roman %{ | |
1 => "I", | |
5 => "V", | |
10 => "X", | |
50 => "L", | |
100 => "C", | |
500 => "D", | |
1000 => "M" | |
} | |
@doc """ | |
Convert the number to a roman number. | |
""" | |
@spec numerals(pos_integer) :: String.t | |
def numerals(number) do | |
number | |
|> digit_list | |
|> to_roman | |
end | |
@doc """ | |
Split an integer into a 4 digit list padded with 0 | |
""" | |
@spec digit_list(pos_integer) :: [pos_integer] | |
def digit_list(number) do | |
number | |
|> to_string | |
|> String.rjust(4, ?0) | |
|> String.codepoints | |
|> Enum.map &(String.to_integer(&1)) | |
end | |
@doc """ | |
Convert 4 digit list into Roman numeral string | |
""" | |
@spec to_roman([pos_integer]) :: String.t | |
def to_roman([thousands, hundreds, tens, ones]) do | |
convert(1000, thousands) <> convert(100, hundreds) <> convert(10, tens) <> convert(1, ones) | |
end | |
defp convert(_, 0), do: "" | |
defp convert(arabic, number) when number < 4, do: duplicate(arabic, number) | |
defp convert(arabic, 4), do: roman_concat(arabic, 5 * arabic) | |
defp convert(arabic, number) when number < 9 do | |
Map.get(@arabic_roman, arabic * 5) <> duplicate(arabic, number - 5) | |
end | |
defp convert(arabic, _), do: roman_concat(arabic, arabic * 10) | |
defp duplicate(arabic, number) do | |
String.duplicate(Map.get(@arabic_roman, arabic), number) | |
end | |
defp roman_concat(first, second) do | |
Map.get(@arabic_roman, first) <> Map.get(@arabic_roman, second) | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
if System.get_env("EXERCISM_TEST_EXAMPLES") do | |
Code.load_file("example.exs") | |
else | |
Code.load_file("roman.exs") | |
end | |
ExUnit.start | |
defmodule RomanTest do | |
use ExUnit.Case, async: true | |
test "1" do | |
assert Roman.numerals(1) == "I" | |
end | |
test "2" do | |
assert Roman.numerals(2) == "II" | |
end | |
test "3" do | |
assert Roman.numerals(3) == "III" | |
end | |
test "4" do | |
assert Roman.numerals(4) == "IV" | |
end | |
test "5" do | |
assert Roman.numerals(5) == "V" | |
end | |
test "6" do | |
assert Roman.numerals(6) == "VI" | |
end | |
test "9" do | |
assert Roman.numerals(9) == "IX" | |
end | |
test "27" do | |
assert Roman.numerals(27) == "XXVII" | |
end | |
test "48" do | |
assert Roman.numerals(48) == "XLVIII" | |
end | |
test "59" do | |
assert Roman.numerals(59) == "LIX" | |
end | |
test "93" do | |
assert Roman.numerals(93) == "XCIII" | |
end | |
test "141" do | |
assert Roman.numerals(141) == "CXLI" | |
end | |
test "163" do | |
assert Roman.numerals(163) == "CLXIII" | |
end | |
test "402" do | |
assert Roman.numerals(402) == "CDII" | |
end | |
test "575" do | |
assert Roman.numerals(575) == "DLXXV" | |
end | |
test "911" do | |
assert Roman.numerals(911) == "CMXI" | |
end | |
test "1024" do | |
assert Roman.numerals(1024) == "MXXIV" | |
end | |
test "3000" do | |
assert Roman.numerals(3000) == "MMM" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for the feedback. Updated by removing the guard clauses for those 2 cases and using an integer in for the match.