Last active
August 14, 2019 14:23
-
-
Save AaronLasseigne/6128642 to your computer and use it in GitHub Desktop.
Roman Numerals Code Kata in Elixir
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 RomanNumeral do | |
def convert(n) when n >= 1000, do: remove_and_continue(n, "M", 1000) | |
def convert(n) when n >= 900, do: remove_and_continue(n, "CM", 900) | |
def convert(n) when n >= 500, do: remove_and_continue(n, "D", 500) | |
def convert(n) when n >= 400, do: remove_and_continue(n, "CD", 400) | |
def convert(n) when n >= 100, do: remove_and_continue(n, "C", 100) | |
def convert(n) when n >= 90, do: remove_and_continue(n, "XC", 90) | |
def convert(n) when n >= 50, do: remove_and_continue(n, "L", 50) | |
def convert(n) when n >= 40, do: remove_and_continue(n, "XL", 40) | |
def convert(n) when n >= 10, do: remove_and_continue(n, "X", 10) | |
def convert(9), do: "IX" | |
def convert(n) when n >= 5, do: remove_and_continue(n, "V", 5) | |
def convert(4), do: "IV" | |
def convert(n), do: String.duplicate("I", n) | |
defp remove_and_continue(total, roman, number) do | |
String.duplicate(roman, div(total, number)) <> convert(rem(total, number)) | |
end | |
end | |
ExUnit.start | |
defmodule RomanNumeralTest do | |
use ExUnit.Case | |
defp is(number, roman) do | |
assert RomanNumeral.convert(number) == roman | |
end | |
test 'convert 1 to "I"' do | |
is(1, "I") | |
end | |
test 'convert 2 to "II"' do | |
is(2, "II") | |
end | |
test 'convert 3 to "III"' do | |
is(3, "III") | |
end | |
test 'convert 4 to "IV"' do | |
is(4, "IV") | |
end | |
test 'convert 5 to "V"' do | |
is(5, "V") | |
end | |
test 'convert 6 to "VI"' do | |
is(6, "VI") | |
end | |
test 'convert 7 to "VII"' do | |
is(7, "VII") | |
end | |
test 'convert 8 to "VIII"' do | |
is(8, "VIII") | |
end | |
test 'convert 9 to "IX"' do | |
is(9, "IX") | |
end | |
test 'convert 10 to "X"' do | |
is(10, "X") | |
end | |
test 'convert 11 to "XI"' do | |
is(11, "XI") | |
end | |
test 'convert 14 to "XIV"' do | |
is(14, "XIV") | |
end | |
test 'convert 19 to "XIX"' do | |
is(19, "XIX") | |
end | |
test 'convert 20 to "XX"' do | |
is(20, "XX") | |
end | |
test 'convert 25 to "XXV"' do | |
is(25, "XXV") | |
end | |
test 'convert 27 to "XXVII"' do | |
is(27, "XXVII") | |
end | |
test 'convert 47 to "XLVII"' do | |
is(47, "XLVII") | |
end | |
test 'convert 1990 to "MCMXC"' do | |
is(1990, "MCMXC") | |
end | |
test 'convert 1954 to "MCMLIV"' do | |
is(1954, "MCMLIV") | |
end | |
test 'convert 2,394 to "MMCCCXCIV"' do | |
is(2394, "MMCCCXCIV") | |
end | |
end |
I know the feeling. I keep having to remind myself that recursion is ok. I'm so used to avoiding it.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Nice! You used recursion where I used Enum.reduce. I'm still trying to develop a feel for idiomatic use of one vs. the other.