Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help me improve this Erlang?

So I'm really interested in Erlang. I can't find an excuse to use it for anything big, but I try to use it for toy problems from time to time.

Right now, I'm implementing a Roman Numeral translator. I'm just doing the "to" part for now, and I'm finding the code is awfully repetitive. It works like a charm, but, well, just look at it:

-module(roman).
-compile([export_all]).

toRoman(N) ->
    toRoman(N, []).

toRoman(0,Acc) ->
    lists:reverse(lists:flatten(Acc));

toRoman(N, Acc) when N >= 1000 ->
    toRoman(N-1000,["M"|Acc]);

toRoman(N,Acc) when N >= 900 ->
    toRoman(N-900,["CM" | Acc]);

toRoman(N,Acc) when N >= 500 ->
    toRoman(N-500,["D" | Acc]);

toRoman(N,Acc) when N >= 400 ->
    toRoman(N-400, ["CD" | Acc]);

toRoman(N,Acc) when N >= 100 ->
    toRoman(N-100, ["C" | Acc]);

toRoman(N,Acc) when N >= 90 ->
    toRoman(N-90, ["XC" | Acc]);

toRoman(N,Acc) when N >= 50 ->
    toRoman(N-50, ["L" | Acc]);

toRoman(N, Acc) when N >= 40 ->
    toRoman(N-40, ["XL" | Acc]);

toRoman(N, Acc) when N >= 10 ->
    toRoman(N-10, ["X" | Acc]);

toRoman(N, Acc) when N >= 9 ->
    toRoman(N-9, ["IX" | Acc]);

toRoman(N, Acc) when N >= 5 ->
    toRoman(N-5, ["V" | Acc]);

toRoman(N, Acc) when N >= 4 ->
    toRoman(N-4, ["IV" | Acc]);

toRoman(N, Acc) ->
    toRoman(N-1, ["I" | Acc]).

test() ->
    Test = fun(X) -> io:format("~p -> ~p~n", [X, toRoman(X)]) end,
    lists:map(Test, [0,1,3,6,23,43,75,87,13,23, 3999, 3998, 2531, 140]).

I feel like there's a much better way to do this. Can anyone provide some insight?

like image 840
Adam Bard Avatar asked Nov 30 '22 11:11

Adam Bard


1 Answers

Actually your code isn't that repetitive. It just looks like it because the text forms a repetitive pattern. But each of your clauses handles a specific case with little logical overlap between them. You could reimplement in a switch statement but you would get a similar repetition. There are just too many cases in a roman numeral translation and I don't think you will be able to avoid the repetitive feel making each of those individual decisions causes.

like image 86
Jeremy Wall Avatar answered Dec 04 '22 02:12

Jeremy Wall