Second approximation of the conversion between old roman and integer digits. Added some error checks and released the roma2int() functionality
%% convert between integer and old roman
%% usage:
%% convert:int2roma(555) -> "DLV"
%% convert:int2roma(999) -> "DCCCCLXXXXVIIII"
%% convert:roma2int("DLV") -> 555
%% convert:roma2int("DCCCCLXXXXVIIII") -> 999
-module(convert).
-export([int2roma/1,roma2int/1]).
i2r(1) -> "I";
i2r(5) -> "V";
i2r(10) -> "X";
i2r(50) -> "L";
i2r(100) -> "C";
i2r(500) -> "D";
i2r(1000) -> "M".
r2i($I) -> 1;
r2i($V) -> 5;
r2i($X) -> 10;
r2i($L) -> 50;
r2i($C) -> 100;
r2i($D) -> 500;
r2i($M) -> 1000;
r2i(X) -> erlang:error("invalid input: " ++ [X]).
roma2int(L) -> catch(lists:sum([r2i(X) || X <- L])).
int2roma(X) when is_integer(X), X < 10000 ->
lists:flatten(int2roma(X,[1000,500,100,50,10,5,1])).
int2roma(_,[]) -> []; %% done
int2roma(X, [H|T])->
[lists:duplicate(X div H, i2r(H))|int2roma(X rem H, T)].
Still a lot to do, like checking the order of character occurences in the string ( roma2int() ), better error messages etc. But for an exercise maybe it’s enough.
- 05-06-2007 update: based on yhara-san’s code I simplified the roma2int() function to one line. It even reports which exactly is the bad symbol. if check in int2roma() replaced by clause with guard.
- 07-06-2007 update: some hints from the okkez-san’s code – no need to have a X>0 clause, cause in case of 0 it just will not execute the lists:duplicate part.
- 13-06-2007 update: List1++List2 construction seems depricated (slow), replaced with \[H|T\] in int2roma()
