Skip to content

Instantly share code, notes, and snippets.

@benwilson512
Last active January 1, 2016 13:38
Show Gist options
  • Save benwilson512/8152129 to your computer and use it in GitHub Desktop.
Save benwilson512/8152129 to your computer and use it in GitHub Desktop.
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