08 September 2006

Erlang programming: Converting numbers to strings

You can see - how to convert numbers to textual representatoin, using erlang/yaws as a backend.
Module to process english is about 100 lines of code.

Here it is:

 
number(N) ->
lists:foldl(
fun
(El, []) -> El;
([], List) -> List;
(El, List) -> List ++ " " ++ El
end,
[], to_number(N)).

to_number(N) when is_list(N) ->
try
to_number(list_to_integer(N), 0)
catch
error:_ -> ["Error converting to text. Please enter integer."]
end;
to_number(N) when is_list(N) -> to_number(list_to_integer(N), 0);
to_number(N) when is_integer(N) -> to_number(N, 0).

to_number({0}, _Order) -> [];
to_number({N}, Order) -> to_number(N, Order);

to_number(0, N) when N>0 ->
[];

to_number(0, 0) -> ["zero"];
to_number(1, _Order) -> ["one"];
to_number(2, _Order) -> ["two"];
to_number(3, _Order) -> ["three"];
to_number(4, _Order) -> ["four"];
to_number(5, _Order) -> ["five"];
to_number(6, _Order) -> ["six"];
to_number(7, _Order) -> ["seven"];
to_number(8, _Order) -> ["eight"];
to_number(9, _Order) -> ["nine"];
to_number(10, _Order) -> ["ten"];
to_number(11, _Order) -> ["eleven"];
to_number(12, _Order) -> ["twelve"];
to_number(20, _Order) -> ["twenty"];
to_number(30, _Order) -> ["thirty"];
to_number(40, _Order) -> ["forty"];
to_number(50, _Order) -> ["fifty"];
to_number(60, _Order) -> ["sixty"];
to_number(70, _Order) -> ["seventy"];
to_number(80, _Order) -> ["eighty"];
to_number(90, _Order) -> ["ninety"];
to_number(N, _Order) when N < 20 ->
[composite(N-10) ++ "teen"];
to_number(N, Order) when N < 100 ->
[ to_number({r(N, 10)}, Order), to_number({m(N, 10)}, Order) ];
to_number(N, Order) when N < 1000 ->
[ to_number({d(N, 100)}, Order), "hundred" | to_number({m(N, 100)}, Order) ];
to_number(N, 0) when is_integer(N) ->
N1 = m(N, 1000),
to_number(
d(N, 1000),
1,
to_number({N1}, 0)
).

to_number(_N, Order, Result) when Order > 11 -> Result;
to_number(0, _Order, Result) -> Result;
to_number(N, Order, Result) ->
Mod = m(N, 1000),
to_number(d(N, 1000),
Order+1,
to_number(Mod, Order) ++ [ order(Order, m(N, 1000)) ] ++ Result).

composite(3) -> "thir"; % for numbers in range 13-19
composite(4) -> "four";
composite(5) -> "fif";
composite(6) -> "six";
composite(7) -> "seven";
composite(8) -> "eight";
composite(9) -> "nine".

order(_, 0) -> "";
order(O, N) -> order(O);
order(O, Number) ->
"order = (" ++ integer_to_list(O) ++ ")".

order(1) -> "thousand"; % 10 3
order(2) -> "million"; % 10 6
order(3) -> "billion"; % 10 9
order(4) -> "trillion"; % 10 12
order(5) -> "quadrillion"; % 10 15
order(6) -> "quintillion"; % 10 18
order(7) -> "sextillion"; % 10 21
order(8) -> "septillion"; % 10 24
order(9) -> "octillion"; % 10 27
order(10) -> "nonillion"; % 10 30
order(11) -> "decillion". % 10 33

d(N, Mod) -> N div Mod.
r(N, Mod) -> (N div Mod)*Mod.
m(N, Mod) -> N rem Mod.

No comments: