mirror of
https://github.com/Xevion/exercism.git
synced 2025-12-06 03:15:01 -06:00
roman numerals elixir
This commit is contained in:
1
elixir/roman-numerals/.exercism/metadata.json
Normal file
1
elixir/roman-numerals/.exercism/metadata.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{"track":"elixir","exercise":"roman-numerals","id":"25ed35ad01214047827de019945b902d","url":"https://exercism.io/my/solutions/25ed35ad01214047827de019945b902d","handle":"Xevion","is_requester":true,"auto_approve":false}
|
||||||
4
elixir/roman-numerals/.formatter.exs
Normal file
4
elixir/roman-numerals/.formatter.exs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# Used by "mix format"
|
||||||
|
[
|
||||||
|
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
|
||||||
|
]
|
||||||
24
elixir/roman-numerals/.gitignore
vendored
Normal file
24
elixir/roman-numerals/.gitignore
vendored
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# The directory Mix will write compiled artifacts to.
|
||||||
|
/_build/
|
||||||
|
|
||||||
|
# If you run "mix test --cover", coverage assets end up here.
|
||||||
|
/cover/
|
||||||
|
|
||||||
|
# The directory Mix downloads your dependencies sources to.
|
||||||
|
/deps/
|
||||||
|
|
||||||
|
# Where third-party dependencies like ExDoc output generated docs.
|
||||||
|
/doc/
|
||||||
|
|
||||||
|
# Ignore .fetch files in case you like to edit your project deps locally.
|
||||||
|
/.fetch
|
||||||
|
|
||||||
|
# If the VM crashes, it generates a dump, let's ignore it too.
|
||||||
|
erl_crash.dump
|
||||||
|
|
||||||
|
# Also ignore archive artifacts (built via "mix archive.build").
|
||||||
|
*.ez
|
||||||
|
|
||||||
|
# Ignore package tarball (built via "mix hex.build").
|
||||||
|
roman_numerals-*.tar
|
||||||
|
|
||||||
85
elixir/roman-numerals/README.md
Normal file
85
elixir/roman-numerals/README.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
# Roman Numerals
|
||||||
|
|
||||||
|
Write a function to convert from normal numbers to Roman Numerals.
|
||||||
|
|
||||||
|
The Romans were a clever bunch. They conquered most of Europe and ruled
|
||||||
|
it for hundreds of years. They invented concrete and straight roads and
|
||||||
|
even bikinis. One thing they never discovered though was the number
|
||||||
|
zero. This made writing and dating extensive histories of their exploits
|
||||||
|
slightly more challenging, but the system of numbers they came up with
|
||||||
|
is still in use today. For example the BBC uses Roman numerals to date
|
||||||
|
their programmes.
|
||||||
|
|
||||||
|
The Romans wrote numbers using letters - I, V, X, L, C, D, M. (notice
|
||||||
|
these letters have lots of straight lines and are hence easy to hack
|
||||||
|
into stone tablets).
|
||||||
|
|
||||||
|
```text
|
||||||
|
1 => I
|
||||||
|
10 => X
|
||||||
|
7 => VII
|
||||||
|
```
|
||||||
|
|
||||||
|
There is no need to be able to convert numbers larger than about 3000.
|
||||||
|
(The Romans themselves didn't tend to go any higher)
|
||||||
|
|
||||||
|
Wikipedia says: Modern Roman numerals ... are written by expressing each
|
||||||
|
digit separately starting with the left most digit and skipping any
|
||||||
|
digit with a value of zero.
|
||||||
|
|
||||||
|
To see this in practice, consider the example of 1990.
|
||||||
|
|
||||||
|
In Roman numerals 1990 is MCMXC:
|
||||||
|
|
||||||
|
1000=M
|
||||||
|
900=CM
|
||||||
|
90=XC
|
||||||
|
|
||||||
|
2008 is written as MMVIII:
|
||||||
|
|
||||||
|
2000=MM
|
||||||
|
8=VIII
|
||||||
|
|
||||||
|
See also: http://www.novaroma.org/via_romana/numbers.html
|
||||||
|
|
||||||
|
## Running tests
|
||||||
|
|
||||||
|
Execute the tests with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ mix test
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pending tests
|
||||||
|
|
||||||
|
In the test suites, all but the first test have been skipped.
|
||||||
|
|
||||||
|
Once you get a test passing, you can unskip the next one by
|
||||||
|
commenting out the relevant `@tag :pending` with a `#` symbol.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
# @tag :pending
|
||||||
|
test "shouting" do
|
||||||
|
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Or, you can enable all the tests by commenting out the
|
||||||
|
`ExUnit.configure` line in the test suite.
|
||||||
|
|
||||||
|
```elixir
|
||||||
|
# ExUnit.configure exclude: :pending, trace: true
|
||||||
|
```
|
||||||
|
|
||||||
|
If you're stuck on something, it may help to look at some of
|
||||||
|
the [available resources](https://exercism.io/tracks/elixir/resources)
|
||||||
|
out there where answers might be found.
|
||||||
|
|
||||||
|
## Source
|
||||||
|
|
||||||
|
The Roman Numeral Kata [http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals](http://codingdojo.org/cgi-bin/index.pl?KataRomanNumerals)
|
||||||
|
|
||||||
|
## Submitting Incomplete Solutions
|
||||||
|
It's possible to submit an incomplete solution so you can see how others have completed the exercise.
|
||||||
39
elixir/roman-numerals/lib/roman_numerals.ex
Normal file
39
elixir/roman-numerals/lib/roman_numerals.ex
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
defmodule RomanNumerals do
|
||||||
|
@values %{
|
||||||
|
"I" => 1,
|
||||||
|
"IV" => 4,
|
||||||
|
"V" => 5,
|
||||||
|
"IX" => 9,
|
||||||
|
"X" => 10,
|
||||||
|
"XL" => 40,
|
||||||
|
"L" => 50,
|
||||||
|
"XC" => 90,
|
||||||
|
"C" => 100,
|
||||||
|
"CD" => 400,
|
||||||
|
"D" => 500,
|
||||||
|
"CM" => 900,
|
||||||
|
"M" => 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Convert the number to a roman number.
|
||||||
|
"""
|
||||||
|
@spec numeral(pos_integer) :: String.t()
|
||||||
|
def numeral(number) do
|
||||||
|
number
|
||||||
|
|> Stream.unfold(fn
|
||||||
|
0 -> nil
|
||||||
|
n -> get_max(n)
|
||||||
|
end)
|
||||||
|
|> Enum.join()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp get_max(n) do
|
||||||
|
numeral =
|
||||||
|
Map.keys(@values)
|
||||||
|
|> Enum.filter(&(Map.get(@values, &1) <= n))
|
||||||
|
|> Enum.max_by(&Map.get(@values, &1))
|
||||||
|
|
||||||
|
{numeral, n - Map.get(@values, numeral)}
|
||||||
|
end
|
||||||
|
end
|
||||||
28
elixir/roman-numerals/mix.exs
Normal file
28
elixir/roman-numerals/mix.exs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
defmodule RomanNumerals.MixProject do
|
||||||
|
use Mix.Project
|
||||||
|
|
||||||
|
def project do
|
||||||
|
[
|
||||||
|
app: :roman_numerals,
|
||||||
|
version: "0.1.0",
|
||||||
|
# elixir: "~> 1.8",
|
||||||
|
start_permanent: Mix.env() == :prod,
|
||||||
|
deps: deps()
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help compile.app" to learn about applications.
|
||||||
|
def application do
|
||||||
|
[
|
||||||
|
extra_applications: [:logger]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Run "mix help deps" to learn about dependencies.
|
||||||
|
defp deps do
|
||||||
|
[
|
||||||
|
# {:dep_from_hexpm, "~> 0.3.0"},
|
||||||
|
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
93
elixir/roman-numerals/test/roman_numerals_test.exs
Normal file
93
elixir/roman-numerals/test/roman_numerals_test.exs
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
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 "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
|
||||||
|
end
|
||||||
2
elixir/roman-numerals/test/test_helper.exs
Normal file
2
elixir/roman-numerals/test/test_helper.exs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ExUnit.start()
|
||||||
|
# ExUnit.configure(exclude: :pending, trace: true)
|
||||||
Reference in New Issue
Block a user