Skip to content

Instantly share code, notes, and snippets.

@jtulk
Created October 9, 2019 07:07
Show Gist options
  • Save jtulk/db2bbfec15a83a191a7d9fa5d922084e to your computer and use it in GitHub Desktop.
Save jtulk/db2bbfec15a83a191a7d9fa5d922084e to your computer and use it in GitHub Desktop.
Coding Challenge: Turn Roman Numerals into their Numeric Equivalents
// a mapping of the numerals and their values
const NUMERALS = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
};
/**
* Given a Roman Numeral, convert it to a number
* @param {string} numeral - a valid Roman Numeral
* @returns {number}
*/
function splitNumerals(numeral) {
const reversedArray = numeral.split("").reverse();
const length = reversedArray.length;
const result = reversedArray.reduce(
(acc, char, i) => {
const val = NUMERALS[char]; // the numeric value of the character
const { buffer, value } = acc;
// final item requires collapsing the buffer
if (i === length - 1) {
if (buffer && val < buffer) {
// handle a subtraction in the initial place
return {
buffer: 0,
value: value + buffer - val
};
} else {
// collapse all the values
return {
buffer: 0,
value: value + val + buffer
};
}
}
// if there's no buffer, then store this value to ensure
// it's not part of a subtraction
if (!buffer) {
return {
buffer: val,
value
};
}
// if it is a subtraction, collapse the value
// substractions by rule can only be a single number
// i.e. IIX is invalid, it would be VIII
if (val < buffer) {
return {
buffer: 0,
value: value + (buffer - val)
};
}
// regular process, add the buffer to the value and
// store the current number
return {
buffer: val,
value: value + buffer
};
},
{ buffer: 0, value: 0 }
);
return result.value + result.buffer;
}
const tests = [
{
expected: 1,
test: "I"
},
{
expected: 5,
test: "V"
},
{
expected: 9,
test: "IX"
},
{
expected: 9,
test: "VIIII"
},
{
expected: 10,
test: "X"
},
{
expected: 14,
test: "XIV"
},
{
expected: 19,
test: "XIX"
},
{
expected: 50,
test: "L"
},
{
expected: 89,
test: "LXXXIX"
},
{
expected: 90,
test: "XC"
},
{
expected: 100,
test: "C"
},
{
expected: 499,
test: "ID"
},
{
expected: 500,
test: "D"
},
{
expected: 1000,
test: "M"
},
{
expected: 2,
test: "II"
},
{
expected: 7,
test: "VII"
},
{
expected: 9,
test: "IX"
},
{
expected: 20,
test: "XX"
},
{
expected: 505,
test: "DV"
},
{
expected: 919,
test: "CMXIX"
}
];
const results = tests.map(t => {
const result = splitNumerals(t.test);
return {
passes: result === t.expected,
expected: t.expected,
result,
test: t.test
};
});
const testResults = results.filter(t => {
return !t.passes;
});
results.forEach(tr => {
console.log(tr);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment