Other Clojure solutions.
(ns roman-numerals)
(def romans [[1000 "M"]
[900 "CM"]
[500 "D"]
[400 "CD"]
[100 "C"]
[90 "XC"]
[50 "L"]
[40 "XL"]
[10 "X"]
[9 "IX"]
[5 "V"]
[4 "IV"]
[1 "I"]])
(defn numerals [n]
(loop [result []
remaining n
[[n roman] & rst] romans]
(if (zero? remaining)
(apply str result)
(if (>= remaining n)
(recur (conj result roman) (- remaining n) romans)
(recur result remaining rst)))))
Other Elixir solutions.
defmodule RomanNumerals do
@numerals %{
1 => "I",
4 => "IV",
5 => "V",
9 => "IX",
10 => "X",
40 => "XL",
50 => "L",
90 => "XC",
100 => "C",
400 => "CD",
500 => "D",
900 => "CM",
1000 => "M"
}
@doc """
Convert the number to a roman number.
"""
@spec numeral(pos_integer) :: String.t()
def numeral(pos_integer) do
@numerals
|> Map.keys()
|> Enum.sort(&(&1 >= &2))
|> Enum.reduce({"", pos_integer}, fn denomination, {roman_numerals, pos_integer} ->
if pos_integer == 0 || denomination / pos_integer > 1 do
{roman_numerals, pos_integer}
else
{
roman_numerals <>
String.duplicate(@numerals[denomination], div(pos_integer, denomination)),
rem(pos_integer, denomination)
}
end
end)
|> elem(0)
end
end
Other Roc solutions.
module [roman]
numerals = Dict.fromList [
(1000, "M"),
(900, "CM"),
(500, "D"),
(400, "CD"),
(100, "C"),
(90, "XC"),
(50, "L"),
(40, "XL"),
(10, "X"),
(9, "IX"),
(5, "V"),
(4, "IV"),
(1, "I"),
]
roman : U64 -> Result Str _
roman = \number ->
nums =
numerals
|> Dict.keys
|> List.sortDesc
(resultString, _) = List.walk nums ("", number) \(result, n), denominator ->
if (n // denominator) >= 1 then
romanChar = numerals |> Dict.get denominator |> Result.withDefault ""
newChars = Str.repeat romanChar (n // denominator)
(Str.concat result newChars, Num.rem n denominator)
else
(result, n)
Ok resultString