53 lines
1.5 KiB
Plaintext
53 lines
1.5 KiB
Plaintext
:- module roman.
|
|
|
|
:- interface.
|
|
|
|
:- import_module io.
|
|
|
|
:- pred main(io::di, io::uo) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module char, int, list, string.
|
|
|
|
main(!IO) :-
|
|
command_line_arguments(Args, !IO),
|
|
filter(is_all_digits, Args, CleanArgs),
|
|
foldl((pred(Arg::in, !.IO::di, !:IO::uo) is det :-
|
|
( Roman = to_roman(Arg) ->
|
|
format("%s => %s", [s(Arg), s(Roman)], !IO), nl(!IO)
|
|
; format("%s cannot be converted.", [s(Arg)], !IO), nl(!IO) )
|
|
), CleanArgs, !IO).
|
|
|
|
:- func to_roman(string::in) = (string::out) is semidet.
|
|
to_roman(Number) = from_char_list(build_roman(reverse(to_char_list(Number)))).
|
|
|
|
:- func build_roman(list(char)) = list(char).
|
|
:- mode build_roman(in) = out is semidet.
|
|
build_roman([]) = [].
|
|
build_roman([D|R]) = Roman :-
|
|
map(promote, build_roman(R), Interim),
|
|
Roman = Interim ++ digit_to_roman(D).
|
|
|
|
:- func digit_to_roman(char) = list(char).
|
|
:- mode digit_to_roman(in) = out is semidet.
|
|
digit_to_roman('0') = [].
|
|
digit_to_roman('1') = ['I'].
|
|
digit_to_roman('2') = ['I','I'].
|
|
digit_to_roman('3') = ['I','I','I'].
|
|
digit_to_roman('4') = ['I','V'].
|
|
digit_to_roman('5') = ['V'].
|
|
digit_to_roman('6') = ['V','I'].
|
|
digit_to_roman('7') = ['V','I','I'].
|
|
digit_to_roman('8') = ['V','I','I','I'].
|
|
digit_to_roman('9') = ['I','X'].
|
|
|
|
:- pred promote(char::in, char::out) is semidet.
|
|
promote('I', 'X').
|
|
promote('V', 'L').
|
|
promote('X', 'C').
|
|
promote('L', 'D').
|
|
promote('C', 'M').
|
|
|
|
:- end_module roman.
|