I can’t tell if my solutions are ingenious or unnecessarily complicated. The logic behind my code is to break up any number <= 4000 into components, so 1234 would become [1000, 200, 30, 4]
and then simply find their equivalents from the tables by using the indices of the Arabic numerals since they correspond to the indices of the Roman numerals. Here’s the code with explanations of each step. Any feedback is appreciated.
function convertToRoman(n) {
let romanTillTen = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX', 'X'];
let arTillTen = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
let romanTillHund = ['XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC', 'C'];
let arTillHund = [20, 30, 40, 50, 60, 70, 80, 90, 100];
let romanTillMil = ['CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM', 'M'];
let arTillMil = [200, 300, 400, 500, 600, 700, 800, 900, 1000];
let romanTill4k = ['MM', 'MMM', 'MMMM'];
let arTill4k = [2000, 3000, 4000];
let numOfzeros = n.toString().length; // find length of n by turning it to a string
let zeros = [1]; // an array to store the inital value to divide n by to get remainders
let rem = [n]; // an array storing the remainders, which will be used to find components
let components = []; // an array to store components, e.g 3999 = [3000, 900, 99]
let final = []; // the final array with corresponding roman numbers
for (let i = 0; i < numOfzeros - 1; i++) { // push numOfzeros - 1 amount of 0's into zeros, so 3999 would result in [1, 0, 0, 0]
zeros.push(0)
}
zeros = Number(zeros.join('')) // turn zeros array into a single number, so [1, 0, 0, 0] becomes 1000
while (zeros >= 10) { // rem.push(3999 % 1000), (999 % 100), (99 % 10)
rem.push(n % zeros)
zeros /= 10
}
for (let i = 0; i < rem.length - 1; i++) { // [3999, 999, 99, 9] becomes [3000, 900, 90], last element not included to avoid NaN
components.push(rem[i] - rem[i + 1])
}
components.push(rem[rem.length - 1]); // push last number of rem into components since it was not in the previous loop
components = components.filter(a => a > 0) // remove any 0 values if any, now components is [3000, 900, 90, 9]
for (let num of components) { // since the indices of Arabic numerals correspond to their Roman equivalents, get the Roman numerals at given indices
if (num <= 10) {
final.push(romanTillTen[arTillTen.indexOf(num)])
} else if (num > 10 && num <= 100) {
final.push(romanTillHund[arTillHund.indexOf(num)])
} else if (num > 100 && num <= 1000) {
final.push(romanTillMil[arTillMil.indexOf(num)])
} else if (num > 1000 && num <= 4000) {
final.push(romanTill4k[arTill4k.indexOf(num)])
}
}
return final.join('')
}
console.log(convertToRoman(3999));