I thought a little more about the classic roman numeral interview problem. The challenge is to deal with the “subtractive” syntax. For example where the numeral for four iv is made of two characters and their order implies a different value…so if you’re mapping each character in a roman numeral to a number you can’t just blindly add them all up. The i before the v must be subtracted.

This all very ASCII thinking though - a string of symbols like xxiv looks like four characters to an English speaking person - but to an ancient Roman - this is three characters. And this iii is one character.

Unicode includes some roman numerals and you can see that “ⅳ” (U+2173) is only one character - made of two glyphs.

With this in mind, you can think about the problem as a task of “correcting” the troublesome “two letter” glyphs and replacing them with a single symbol - then just doing some dumb arithmetic to get your integer value.

This works because Roman numerals are a finite set, unlike the Arabic number system. We can use this to our advantage and write a dumber function.

function toDecimal(numeral) {
  const troublesomeGlyphs = {
    "iv": "ⅳ", // 4
    "ix": "ⅸ", // 9
    "xl": "f", // 40
    "xc": "n", // 90
    "cd": "F", // 400
    "cm": "N", // 900
  };

  const sym = {
    "i": 1,
    "ⅳ": 4,
    "v": 5,
    "ⅸ": 9,
    "x": 10,
    "l": 50,
    "f": 40,
    "n": 90,
    "c": 100,
    "F": 400,
    "d": 500,
    "N": 900,
    "m": 1000,
  };
  numeral = numeral.toLowerCase();
  (Object.keys(troublesomeGlyphs)).forEach(k => {
    numeral = numeral.replace(k, troublesomeGlyphs[k]);
  });
  return numeral
    .split('')
    .map(n => sym[n])
    .reduce((total, current) => total + current, 0);
}