Task

Create a function taking a positive integer as its parameter and returning a string containing the Roman numeral representation of that integer. Modern Roman numerals are written by expressing each digit separately, starting with the left most digit and skipping any digit with a value of zero.



In Roman numerals:

 1990 is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC
 2008 is written as 2000=MM, 8=VIII; or MMVIII
 1666 uses each Roman symbol in descending order: MDCLXVI


 
MODULE RomanNumeralsEncode;
 
FROM Strings IMPORT
  Append;
FROM STextIO IMPORT
  WriteString, WriteLn;
 
CONST
  MaxChars = 15;
  (* 3888 or MMMDCCCLXXXVIII (15 chars) is the longest string properly encoded
     with these symbols. *)
 
TYPE
  TRomanNumeral = ARRAY [0 .. MaxChars - 1] OF CHAR;
 
PROCEDURE ToRoman(AValue: CARDINAL; VAR OUT Destination: ARRAY OF CHAR);
TYPE
  TRomanSymbols = ARRAY [0 .. 1] OF CHAR;
  TWeights = ARRAY [0 .. 12] OF CARDINAL;
  TSymbols = ARRAY [0 .. 12] OF TRomanSymbols;
CONST
  Weights = TWeights {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
  Symbols = TSymbols {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX",
    "V", "IV", "I"};
VAR
  I: CARDINAL;
BEGIN
  Destination := "";
  I := 0;
  WHILE (I <= HIGH(Weights)) AND (AValue > 0) DO
    WHILE AValue >= Weights[I] DO
      Append(Symbols[I], Destination);
      AValue := AValue - Weights[I]
    END;
    INC(I);
  END;
END ToRoman;
 
VAR
  Numeral: TRomanNumeral;
 
BEGIN
  ToRoman(1990, Numeral); WriteString(Numeral); WriteLn; (* MCMXC *)
  ToRoman(2018, Numeral); WriteString(Numeral); WriteLn; (* MMXVIII *)
  ToRoman(3888, Numeral); WriteString(Numeral); WriteLn; (* MMMDCCCLXXXVIII *)
END RomanNumeralsEncode.
 