Romand to Numeral
by dannye
HTML
We are so used to reading from Left to Right, we forgot about the Right-to-Left alternatives...
<hr>
<script>
const romanToArabic = (input) => [...input].reduceRight((
acc,
letter,
idx,
arr,
value = { m: 1000, d: 500, c: 100, l: 50, x: 10, v: 5, i: 1 } [letter.toLowerCase()],
sameLetter = letter == arr[idx + 1] // ignore IIX notation
) => {
if (value < acc.high && !sameLetter) {
acc.Arabic += -value;
} else {
acc.Arabic += acc.high = value;
}
console.log(idx, letter, acc, 'value:', value, acc.high, arr[idx + 1]);
return acc;
}, { high: 0,Arabic: 0 }).Arabic; // return Arabic value
// TESTS
Object.entries({
"cxxiv": 124,
"ix": 9,
"iix": 10,
"xL": 40,
"MMMDXLIX": 3549,
"MMMMCMXCIX": 4999,
"MDCLXVI": 1666,
"MIII": 1003
}).map(([roman, value, converted = romanToArabic(roman)]) => {
document.body.append(roman, "=", converted, document.createElement("HR"));
console.assert(converted == value, "wrong conversion,", roman, "must be", value)
})
</script>
JavaScript
/* let input = 999;
Object.entries({
"M": 1000,
"D": 500,
"c": 100,
"l": 50,
"x": 10,
"v": 5,
"i": 1
}).reduce((acc,[letter, value],idx,arr) => {
console.log(idx,input,acc);
let letterRepeat = ~~(input/value);
input -= letterRepeat * value;
acc += letter.repeat(letterRepeat);
console.log(letter,input) //999
return acc;
},"");
*/