New improved int2roma() and roma2int() functions
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.
- 07-06-2007 update: List1++List2 construction seems depricated (slow), replaced with [H|T] in int2roma().