53 lines
1.1 KiB
Plaintext
53 lines
1.1 KiB
Plaintext
MODULE RomanNumerals;
|
|
FROM InOut IMPORT WriteString, WriteCard, WriteLn;
|
|
FROM Strings IMPORT Length;
|
|
|
|
(* Convert given Roman numeral to binary *)
|
|
PROCEDURE DecodeRoman(s: ARRAY OF CHAR): CARDINAL;
|
|
VAR i, d, len, acc: CARDINAL;
|
|
|
|
PROCEDURE Digit(d: CHAR): CARDINAL;
|
|
BEGIN
|
|
CASE CHR( BITSET(ORD(d)) + BITSET{5} ) OF (* lowercase *)
|
|
'm': RETURN 1000;
|
|
| 'd': RETURN 500;
|
|
| 'c': RETURN 100;
|
|
| 'l': RETURN 50;
|
|
| 'x': RETURN 10;
|
|
| 'v': RETURN 5;
|
|
| 'i': RETURN 1;
|
|
ELSE
|
|
RETURN 0;
|
|
END;
|
|
END Digit;
|
|
BEGIN
|
|
len := Length(s);
|
|
acc := 0;
|
|
FOR i := 0 TO len-1 DO
|
|
d := Digit(s[i]);
|
|
IF d=0 THEN RETURN 0; END;
|
|
|
|
IF (i # len-1) AND (d < Digit(s[i+1])) THEN
|
|
acc := acc - d;
|
|
ELSE
|
|
acc := acc + d;
|
|
END;
|
|
END;
|
|
RETURN acc;
|
|
END DecodeRoman;
|
|
|
|
PROCEDURE Show(s: ARRAY OF CHAR);
|
|
BEGIN
|
|
WriteString(s);
|
|
WriteString(": ");
|
|
WriteCard(DecodeRoman(s), 0);
|
|
WriteLn();
|
|
END Show;
|
|
|
|
BEGIN
|
|
Show("MCMXC");
|
|
Show("MDCLXVI");
|
|
Show("mmvii");
|
|
Show("mmxxi");
|
|
END RomanNumerals.
|