Last active
January 1, 2016 13:38
-
-
Save benwilson512/8152129 to your computer and use it in GitHub Desktop.
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 Generator do | |
# Generates a method like the following | |
# def to_word(n) when n >= 1_000 do | |
# [to_word(div(n, 1_000)), "thousand,", to_word(rem n, 1_000)] | |
# end | |
defmacro gen_method(input) do | |
quote bind_quoted: [input: input] do | |
def to_word(n) when n >= unquote(input[:num]) do | |
[to_word(div(n, unquote(input[:num]))), "#{unquote(input[:text])},", to_word(rem n, unquote(input[:num]))] | |
end | |
end | |
end | |
end | |
defmodule NumFun do | |
require Generator | |
def word(n) do | |
to_word(n) | |
|> List.flatten | |
|> Enum.filter(&(&1)) | |
|> Enum.join(" ") | |
end | |
[ | |
[num: 1_000, text: "thousand"], | |
[num: 1_000_000, text: "million"], | |
[num: 1_000_000_000, text: "billion"], | |
[num: 1_000_000_000_000, text: "trillion"], | |
[num: 1_000_000_000_000_000, text: "quadrillion"], | |
[num: 1_000_000_000_000_000_000, text: "quintillion"] | |
] |> Enum.reverse | |
|> Enum.map(&Generator.gen_method(&1)) | |
def to_word(0), do: nil | |
def to_word(1), do: "one" | |
def to_word(2), do: "two" | |
def to_word(3), do: "three" | |
def to_word(4), do: "four" | |
def to_word(5), do: "five" | |
def to_word(6), do: "six" | |
def to_word(7), do: "seven" | |
def to_word(8), do: "eight" | |
def to_word(9), do: "nine" | |
def to_word(10), do: "ten" | |
def to_word(11), do: "eleven" | |
def to_word(12), do: "twelve" | |
def to_word(13), do: "thirteen" | |
def to_word(15), do: "fifteen" | |
def to_word(20), do: "twenty" | |
def to_word(30), do: "thirty" | |
def to_word(40), do: "forty" | |
def to_word(50), do: "fifty" | |
def to_word(80), do: "eighty" | |
def to_word(n) when n >= 100 do | |
[to_word(div(n, 100)), "hundred", with_and?(to_word(rem n, 100))] | |
end | |
def to_word(n) when n > 13 and n < 20 do | |
to_word(rem n, 10) <> "teen" | |
end | |
def to_word(n) when n < 100 and rem(n, 10) == 0 do | |
to_word(div n, 10) <> "ty" | |
end | |
def to_word(n) when n < 100 and rem(n, 10) != 0 do | |
[to_word(div(n, 10) * 10), to_word(rem n, 10)] | |
end | |
def with_and?(n) when n != nil do | |
["and", n] | |
end | |
def with_and?(n), do: nil | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment