say
This commit is contained in:
74
elixir/say/lib/say.ex
Normal file
74
elixir/say/lib/say.ex
Normal file
@@ -0,0 +1,74 @@
|
||||
defmodule Say do
|
||||
@in_english_19 %{
|
||||
1 => "one",
|
||||
2 => "two",
|
||||
3 => "three",
|
||||
4 => "four",
|
||||
5 => "five",
|
||||
6 => "six",
|
||||
7 => "seven",
|
||||
8 => "eight",
|
||||
9 => "nine",
|
||||
10 => "ten",
|
||||
11 => "eleven",
|
||||
12 => "twelve",
|
||||
13 => "thirteen",
|
||||
14 => "fourteen",
|
||||
15 => "fifteen",
|
||||
16 => "sixteen",
|
||||
17 => "seventeen",
|
||||
18 => "eighteen",
|
||||
19 => "nineteen"
|
||||
}
|
||||
|
||||
@in_english_100 %{
|
||||
2 => "twenty",
|
||||
3 => "thirty",
|
||||
4 => "forty",
|
||||
5 => "fifty",
|
||||
6 => "sixty",
|
||||
7 => "seventy",
|
||||
8 => "eighty",
|
||||
9 => "ninety"
|
||||
}
|
||||
|
||||
@doc """
|
||||
Translate a positive integer into English.
|
||||
"""
|
||||
@spec in_english(integer) :: {atom, String.t()}
|
||||
def in_english(number) when number < 0 or number > 999_999_999_999,
|
||||
do: {:error, "number is out of range"}
|
||||
|
||||
def in_english(0), do: {:ok, "zero"}
|
||||
|
||||
def in_english(number) do
|
||||
{:ok,
|
||||
number
|
||||
|> Integer.digits()
|
||||
|> Enum.reverse()
|
||||
|> Enum.chunk_every(3)
|
||||
|> Enum.with_index(fn element, index -> in_english_part(element, index) end)
|
||||
|> Enum.reverse()
|
||||
|> List.flatten()
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.join(" ")
|
||||
}
|
||||
end
|
||||
|
||||
@spec in_english_part([integer], integer) :: String.t()
|
||||
defp in_english_part([0, 0, 0], _index), do: []
|
||||
defp in_english_part(element, 3), do: [do_in_english_part(element) | ["billion"]]
|
||||
defp in_english_part(element, 2), do: [do_in_english_part(element) | ["million"]]
|
||||
defp in_english_part(element, 1), do: [do_in_english_part(element) | ["thousand"]]
|
||||
defp in_english_part(element, 0), do: [do_in_english_part(element)]
|
||||
|
||||
defp do_in_english_part([d1, d2, d3]) when d3 != 0, do: [@in_english_19[d3], "hundred" | [do_in_english_part([d1, d2])]]
|
||||
defp do_in_english_part([d1, d2, 0]), do: do_in_english_part([d1, d2])
|
||||
defp do_in_english_part([d1, d2]) when d2 < 2, do: @in_english_19[Integer.undigits([d2, d1])]
|
||||
defp do_in_english_part([0, d2]) when d2 > 1, do: @in_english_100[d2]
|
||||
|
||||
defp do_in_english_part([d1, d2]) when d2 > 1,
|
||||
do: @in_english_100[d2] <> "-" <> @in_english_19[d1]
|
||||
|
||||
defp do_in_english_part([d1]), do: @in_english_19[d1]
|
||||
end
|
||||
Reference in New Issue
Block a user