I found this interesting question about converting numbers into "words":
I would really like to see how you would implement this efficiently in Erlang.
I found this interesting question about converting numbers into "words":
I would really like to see how you would implement this efficiently in Erlang.
int2text(Num) when is_integer(Num) -> int2text(integer_to_list(Num));
int2text(Num) ->
Segs = segment(0, lists:reverse(Num)),
Words = lists:reverse([Seg || Seg <- Segs, Seg =/= []]),
string:join(Words, " ").
segment(Ths, "") -> segment3(Ths, [$0,$0,$0]);
segment(Ths, [A]) -> segment3(Ths, [$0,$0,A]);
segment(Ths, [A,B]) -> segment3(Ths, [$0,B,A]);
segment(Ths, [A,B,C|Num]) -> segment3(Ths, [C,B,A]) ++ segment(Ths+1, Num).
segment3(_Ths, [$0,$0,$0]) -> [];
segment3(Ths, [$0,A,B]) -> [thousands(Ths)] ++ segment2([A,B]);
segment3(Ths, [A,B,C]) -> [thousands(Ths)] ++ segment2([B,C]) ++ ["hundred", ones([A])].
segment2([$0,A]) -> [ones([A])];
segment2([$1,A]) -> [ones([$1,A])];
segment2([A,B]) -> [ones([B]), tens([A])].
ones("0") -> "";
ones("1") -> "one";
...
ones("18") -> "eighteen";
ones("19") -> "nineteen".
tens("2") -> "twenty";
...
tens("9") -> "ninety".
thousands(0) -> "";
thousands(1) -> "thousand";
thousands(2) -> "million";
...
-module(num2word).
-export([num2word/1]).
num2word(0) ->
"Zero";
num2word(N) when N < 10 ->
lists:nth(N, ["One", "Two", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine"]);
num2word(N) when N < 20 ->
lists:nth(N-9, [ "Ten", "Eleven", "Twelve",
"Thirteen", "Fourteen", "Fifteen",
"Sixteen", "Seventeen", "Eighteen",
"Nineteen"]);
num2word(N) when (N < 100) and ((N rem 10) =:= 0) ->
lists:nth((N div 10)-1, ["Twenty", "Thirty", "Forty", "Fifty",
"Sixty", "Seventy", "Eighty", "Ninety"]);
num2word(N) when N < 100 ->
num2word((N div 10) * 10) ++ " " ++ num2word(N rem 10);
num2word(N) when ((N rem 100) =:= 0) ->
{Scale, Name} = scale(N),
Result = num2word(N div Scale) ++ " " ++ Name,
case (N rem Scale) of
0 -> Result;
Remainder -> Result ++ " " ++ num2word(Remainder)
end;
num2word(N) ->
{Scale, _} = scale(N),
num2word((N div Scale) * Scale) ++ " " ++ num2word(N rem Scale).
scale(N) when N < 1000 ->
{100, "Hundred"};
scale(N) when N < 1000000 ->
{1000, "Thousand"};
scale(N) when N < 1000000000 ->
{1000000, "Million"};
scale(N) when N < 1000000000000 ->
{1000000000, "Billion"};
scale(N) when N < 1000000000000000 ->
{1000000000000, "Trillion"};
scale(N) when N < 1000000000000000000 ->
{1000000000000000, "Quadrillion"};
scale(N) when N < 1000000000000000000000 ->
{1000000000000000000, "Quintillion"}.
Tests: