Created
October 9, 2019 07:07
-
-
Save jtulk/db2bbfec15a83a191a7d9fa5d922084e to your computer and use it in GitHub Desktop.
Coding Challenge: Turn Roman Numerals into their Numeric Equivalents
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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