Wednesday, May 9th, 2018

Roman Numerals, Groovy Style

Your project is already late when you discover in the small print of the contract that the system in development "SHALL manage Roman digits in chapter numbers". You frantically search the 'Net and, yes there are solutions. Some of them seem complicated on first sight. Do you wish for less convoluted code? You've got it.

Here is an attempt at a Groovy solution, i.e. compact but not obscure code. The techniques are, of course, borrowed from other people on the 'Net. The parse method relies heavily on the Groovy switch statement. The print method uses floorKey, a method that GDK adds to the Java API. Both are recursive.

The main contribution may be that the parsing method does a fairly complete validation of its input.

GROOVY:

  1. span style="color: #a1a100;">import java.util.regex.Matcher
  2.  
  3. /**
  4. * Class for processing Roman numerals.
  5. *//**
  6.   * Convert a Roman numeral to an Integer value with decent validation.
  7.   * @param numeral must be a string of Roman digits,
  8.   * @throws NumberFormatException if the numeral is invalid.
  9.   */// Cases not detected by other regex.
  10. "Invalid Roman numeral: ${numeral}"'IX''IV''III''II''I'"Invalid Roman numeral: ${numeral}")
  11.   }
  12. }
  13.  
  14. /**
  15. * The recursive part of parsing.
  16. * @param value must be the integer value collected so far.
  17. * The method picks up the tail of the last regex match.
  18. *//**
  19. * Format an integer as a Roman numeral.
  20. * @param value must be the integer to format,
  21. * @throws IllegalArgumentException if the integer is out of range (1..3999).
  22. */"Integer out of range: ${value}"'M', 900: 'CM', 500: 'D', 400: 'CD',
  23.                100: 'C', 90: 'XC', 50: 'L', 40: 'XL',
  24.                10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I'])
  25. }

You may download a zipped archive here containing the above code (with better indenting) and also a Spock unit test.

Comments are closed.