Search code examples
erlangnumberscode-golfwords

How to convert numbers to words in Erlang?


I found this interesting question about converting numbers into "words":

Code Golf: Number to Words

I would really like to see how you would implement this efficiently in Erlang.


Solution

  • -module(int2txt).
    -export([convert/1]).
    
    convert(0) -> "zero";
    convert(N) -> convert1(N).
    
    convert1(0) -> "";
    convert1(N) when N>=1000 ->
        join(convert_thou(thoubit(N), 0),convert1(N rem 1000));
    convert1(N) when N>=100 ->
        join(convert1(N div 100),"hundred",convert1(N rem 100));
    convert1(N) when N>=20 ->
        join(tens((N div 10)-1) ++"ty",convert1(N rem 10));
    convert1(N) when N>=13 -> teens(N-12) ++ "teen";
    convert1(N) -> ones(N).
    
    convert_thou({0,0},_) -> "";
    convert_thou({0,N2},C) -> convert_thou(thoubit(N2),C+1);
    convert_thou({N,N2},C) -> join(convert_thou(thoubit(N2),C+1),
                       convert1(N),thouword(C)).
    
    thoubit(N) -> {(N div 1000) rem 1000,N div 1000}.
    
    ones(N) -> element(N,{"one","two","three","four","five","six","seven",
                  "eight","nine","ten","eleven","twelve"}).
    tens(N) -> element(N,{"twen","thir","for","fif","six","seven","eigh","nine"}).
    teens(2) -> "four";
    teens(N) -> tens(N+1).
    thouword(0) -> "thousand";
    thouword(C) -> illions(C) ++ "illion".
    illions(N) -> element(N,{"m","b","tr","quadr","quint","sex","sept",
                             "oct","non","dec"}).
    
    join(X,Y,Z) -> join(join(X,Y),Z).
    join("",X) -> X;
    join(X,"") -> X;
    join(X,Y) -> X++" "++Y.
    

    Tests:

    1> int2txt:convert(0).
    "zero"
    2> int2txt:convert(1024).
    "one thousand twenty four"
    3> int2txt:convert(1048576).
    "one million forty eight thousand five hundred seventy six"
    4> int2txt:convert(1073741824).
    "one billion seventy three million seven hundred forty one thousand
    eight hundred twenty four"
    5> int2txt:convert(1000001).   
    "one million one"