Skip to content

Instantly share code, notes, and snippets.

@cryptoquick
Forked from ypopovych/roman-number.js
Created February 21, 2018 01:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cryptoquick/f2ad9ad8d47ff90c40cb15d04c9f61f8 to your computer and use it in GitHub Desktop.
Save cryptoquick/f2ad9ad8d47ff90c40cb15d04c9f61f8 to your computer and use it in GitHub Desktop.
Several ways to do Rome numbers converter
const romanNumerals = [
[1000, "M"], [500, "D"], [100, "C"],
[50, "L"], [10, "X"], [5, "V"], [1, "I"]
];
const toRomeRecursion = (function convert(index, number) {
if (number === 0) return '';
let [romanNumber, romanLiteral] = romanNumerals[index];
if (number < romanNumber) return convert(index+1, number);
let [minRomanNumber, minRomanLiteral] = romanNumerals[index+index%2];
let [prevRomanNumber, prevRomanLiteral] = romanNumerals[index-1] || [romanNumber*10, ''];
return (number + minRomanNumber) >= prevRomanNumber ?
minRomanLiteral + prevRomanLiteral + convert(index+1+index%2, number%minRomanNumber) :
romanLiteral.repeat(number / romanNumber) + convert(index+1, number%romanNumber)
}).bind(null, 0);
function toRomeImperative(number) {
let index = 0, value = '';
while(number > 0) {
let [romanNumber, romanLiteral] = romanNumerals[index];
if (number >= romanNumber) {
let [minRomanNumber, minRomanLiteral] = romanNumerals[index+index%2];
let [prevRomanNumber, prevRomanLiteral] = romanNumerals[index-1] || [romanNumber*10, ''];
if ((number + minRomanNumber) >= prevRomanNumber) {
value += minRomanLiteral + prevRomanLiteral;
number %= minRomanNumber;
index += index%2;
} else {
value += romanLiteral.repeat(number / romanNumber);
number %= romanNumber;
}
}
index++;
}
return value;
}
function toRomeReducer(number) {
return romanNumerals.reduce(([result, number], [romanNumber, romanLiteral], index, numbers) => {
if (number >= romanNumber) {
let [minRomanNumber, minRomanLiteral] = numbers[index+index%2];
let [prevRomanNumber, prevRomanLiteral] = numbers[index-1] || [romanNumber*10, ''];
return (number + minRomanNumber) >= prevRomanNumber ?
[result + minRomanLiteral + prevRomanLiteral, number%minRomanNumber] :
[result + romanLiteral.repeat(number / romanNumber), number%romanNumber];
}
return [result, number];
}, ['', number])[0];
}
for (let i = 1; i < 4000; i++) {
console.log(i, toRomeImperative(i), toRomeRecursion(i), toRomeReducer(i));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment