
# romans.py
# Convert decimals <-> Roman numerials.
# info: https://en.wikipedia.org/wiki/Roman_numerals

# 1000 <->"M", 900 <->"CM", 500 <->"D"...
decimalDens = [1000,900,500,400, 100, 90, 50, 40, 10, 9, 5,4,1]
romanDens   = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"]

def num2Roman(dec):
  # sanity checks
  if dec <= 0:
    raise ValueError("It must be a positive")
  elif dec >= 4000:   
    raise ValueError("It must be lower than MMMM(4000)")
  return toRoman(dec, "", decimalDens, romanDens)


def toRoman(num, s, decs, romans):
  if decs != []:
    if num < decs[0]:
      # deal with the rest of the denomination
      return toRoman(num, s, decs[1:], romans[1:])  
    else:
      # reduce this denomation till num < desc[0]
      return toRoman(num-decs[0], s+romans[0], decs, romans)  
  else:
    return s


def roman2Num(str):
  str = str.upper()
  res = 0
  i = 0
  while (i < len(str)):
    s1 = toDecimal(str[i])
    if (i+1 < len(str)):
      s2 = toDecimal(str[i+1])
      if (s1 >= s2):
        res += s1
        i += 1
      else:  # s1 < s2
        res += (s2 - s1)
        i += 2
    else:
      res += s1
      i += 1
  return res

def toDecimal(ch):
  # Roman symbol to decimal
  try:
    idx = romanDens.index(ch)
    return decimalDens[idx]
  except ValueError:
    print(ch, "not recognized; using 1")
    return 1



if __name__ == "__main__":
  rs = []
  for n in [12, 44, 57, 111, 1910, 2024]:
    r = num2Roman(n)
    rs.append(r)
    print(n, r)
  print("---------------")
  for rom in rs:
    print(rom, roman2Num(rom)) 

