
// Roman.java
// Andrew Davison, ad@coe.psu.ac.th, April 2023

/* Convert an integer into Roman Numerals, and back again.
   https://en.wikipedia.org/wiki/Roman_numerals
 
   Usage:
     > compile Roman.java
     > run Roman <n>
   e.g. 
    > run Roman 2023
    Roman: MMXXIII
    Back to Arabic: 2023

*/

import java.util.*;


public class Roman
{
  private static final int[] ARABIC = new int[] {
            1000, 900, 500, 400, 100, 90, 50, 
            40, 10, 9, 5, 4, 1 };

  private static final String[] ROMAN = new String[] {
            "M", "CM", "D", "CD", "C", "XC", "L", 
            "XL", "X", "IX", "V", "IV", "I" };

  private static final Map<Character,Integer>  
             ROMAN_ARAB = Map.of(
                     'I', 1,
                     'V', 5,
                     'X', 10,
                     'L', 50,
                     'C', 100,
                     'D', 500,
                     'M', 1000 );


  public static void main(String[] args)
  {
    if (args.length != 1) {
      System.out.println("Usage: run Roman <n>");
      return;
    }
    int n = Math.abs(Nut.parseInt(args[0]));
    String romanStr = intToRoman(n);
    System.out.println("Roman: " + romanStr);

    System.out.println("Back to Arabic: " + romanToInt(romanStr));
  } // end of main()


  private static String intToRoman(int n)
  {
    if (n <= 0)
      return "";

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < ARABIC.length; i++) {
      int quot = n / ARABIC[i];
      for (int b = 0; b < quot; b++)
        sb.append(ROMAN[i]);
      n -= quot * ARABIC[i];  // remove remainder
    }
    return sb.toString();
  } /* intToRoman */



  private static int romanToInt(String s)
  {
    s = s.toUpperCase();
    char prevCh = ' ';
    int sum = 0;
    int prevNum = 0;

    for (int i = s.length()-1; i >= 0; i--) {
      char currCh = s.charAt(i);
      if (prevCh != ' ') {
        if (ROMAN_ARAB.get(prevCh) > prevNum)
          prevNum = ROMAN_ARAB.get(prevCh);  
                       // increase previous number
      }
      int currNum = ROMAN_ARAB.get(currCh);
      if (currNum >= prevNum)
        sum += currNum;
      else
        // subtract until current not greater then prev. number
        sum -= currNum;
      prevCh = currCh;
    }

    return sum;
  } /* romanToInt */


}  // end of Roman class
