# Roman Numeral Converter Challenge

Roman Numeral Converter Challenge
0.0 0

#91

I don’t know ES6, so here is my ES5 approach, that took a few attempts to get it working.

``````/*
** Function: Convert a number into a Roman Numeral.
** @function convertToRoman
** @summary  Convert a number into a Roman Numeral.
** @param 	 {number}
** @returns  {string} Roman Numeral
*/
function convertToRoman(num) {
'use strict';

var base  = [1000,500,100,50,10,5,1];
var roman = ['M','D','C','L','X','V','I'];
var result = "";
// 'I' = 1, 'V' = 5, 'X' = 10, 'L' = 50, 'C' = 100, 'D' = 500, 'M' = 1000

base.forEach( function(value, i) {

var ch = roman[i];
if ( ch === 'V' || ch === 'L' || ch === 'D' ) {
if ( num >= base[i+1]*9 ) {
result += roman[i+1] + roman[i-1];
num -= ( base[i-1] - base[i+1] );
}
else if ( num >= value - base[i+1] && num < value ) {
result += roman[i+1] + roman[i];
num -= ( base[i] - base[i+1] );
}
}

while ( num >= value ) {
result += roman[i];
num -= value;
}
});
return result;
}
``````

#92

I did something a bit similar.
I really like the .forEach() method.

function convertToRoman(num) {
var romanNum = [
[“I”,“II”,“III”,“IV”,“V”,“VI”,“VII”,“VIII”,“IX”],
[“X”,“XX”,“XXX”,“XL”,“L”,“LX”,“LXX”,“LXXX”,“XC”],
[“C”,“CC”,“CCC”,“CD”,“D”,“DC”,“DCC”,“DCCC”,“CM”,],
[“M”,“MM”,“MMM”]
] ;

var arr = num.toString().split("").reverse();
var rNums = [];
romanNum.forEach(function (a, i){
romanNum[i].forEach(function (b, j){
if((j + 1) == arr[i]){
rNums.unshift(b);
}
});

});
var result = rNums.join(’’);
return result;
}

convertToRoman(3643);

#93

I’ve been impressed by the clever use of Math.floor from other postings. I didn’t use it. I also like the string repeat method, which I wasn’t even aware of until looking through posts. My first attempt is below, which solved the problem but seems like a brute force attempt at solving the problem.

``````
/*js hint esnext:true */

function wrapper(num){

const romNumerals = [["I","IV","V","IX"],["X","XL","L","XC"],["C","CD","D","CM"],"M"]; //array of arrays for Roman Numerals

const decimalNot = [[1,4,5,9],[10,40,50,90],[100,400,500,900],1000]; //corresponding array of arrays with decimal notation

function convertToString(num){

const numSplitArray = num.toString().split("").reverse().map((currVal,index) => Number(currVal+"e"+index)); //convert to string and split number, adjust number based on ones,tens,hundreds,thousands

return convert(numSplitArray);

}

function convert(arr){

let updateArray = [], //will  push all for loop results to this array

i,

joinedArray = [], //final array will be joined into this array

arrLen = arr.length;

for(i=0; i<3; i++){ //loop through the ones, tens, and hundreds

if(arr[i]===0 || !arr[i]) {

continue; } //if the ones,tens, or hundreds place is zero, or undefined, skip current loop iteration

else if(decimalNot[i].indexOf(arr[i]) === -1){ //if the corresponding roman numeral isn't present in the array, execute below

let j=0, //define var for while loop

inc = Math.pow(10,i); //increment based on the ones,tens,hundreds which is determined by the loop i value

while(decimalNot[i].indexOf(arr[i]-j) === -1){ //while the number isn't present in the decimal notation array keep looping

j += inc; //increment based on ones,tens,hundreds
updateArray.push(romNumerals[i][0]); //push the corresponding roman numeral to the array (I, or X, or C)
}

updateArray.push(romNumerals[i][decimalNot[i].indexOf(arr[i]-j)]); //push the remainder (V, or L, or D)

} else {  //if the number is directly available, go ahead and push it

updateArray.push(romNumerals[i][decimalNot[i].indexOf(arr[i])]);

}

}

if(arr[3]){ //if there is a thousands place, push an M for each thousand

let thousandsValue = arr[3]/1000;

for(let k=0; k<thousandsValue; k++){

updateArray.push(romNumerals[3]);
}

}

joinedArray = updateArray.reverse().join(""); //reverse and join everything

console.log(joinedArray);
//return joinedArray;

}

return convertToString(num);

}

wrapper(36);
``````

I then started from scratch and was determined to use only a functional declarative approach. Less mutating arrays and looping, more .map and recursion. I think it’s easier to understand, but I’m not sure I decreased the amount of code by much. As I’ve read, clever and concise problem solving is what we’re really after.

``````/* jshint esnext: true */

//declarative version of the roman numeral problem, from scratch.  No mutating state (push, splice, etc.), no var or let, and a recursive function.

const romNumerals = [["I","IV","V","IX"],["X","XL","L","XC"],["C","CD","D","CM"],"M"]; //array of arrays for Roman Numerals

const decimalNot = [[1,4,5,9],[10,40,50,90],[100,400,500,900],1000]; //corresponding array of arrays with decimal notation

const convertToRoman = num => {

const numSplitArray = num.toString()
.split("")
.reverse()
.map((currVal,index) => Number(currVal+"e"+index)); //convert to string and split number, adjust number based on ones,tens,hundreds,thousands

return finalArray(numSplitArray);

}

function reverseConvertNum (num,numIndex){

const numIsZero = isZero(num, numIndex);

if(numIsZero) return;

const convNumber = convertNum(num, numIndex);

if(!arrIncludesNum(num,numIndex)) return convNumber.split("").reverse().join("");

return convNumber;
}

const isZero = (num, numIndex) => num === 0;

function convertNum (num, numIndex){

const adjustIndex = Number(1 + "e" + numIndex);

if (arrIncludesNum(num, numIndex)) {

return romNumerals[numIndex][decimalNot[numIndex].indexOf(num)]; }

}

const arrIncludesNum = (num, numIndex) => decimalNot[numIndex].includes(num); //does the decimal array already contain the number

const hasThousands = array => array[3]; //does the number passed by the user have a thousands place

function writeThousands (array){

if (hasThousands(array)) {

let kArray = [];

kArray.length = array[3]/1000;

return kArray.fill(0).map(returnEms).join("");

}

return "";

}

const returnEms = num => "M";

function finalArray (array){

const newArray = array.slice(0,3).map(reverseConvertNum).reverse().join(""),

thousandsPlace = writeThousands(array);

return thousandsPlace + newArray;
}

console.log(convertToRoman(700));

``````

Cheers!

#94

This is a really cool thread. I’ve seen some other examples that are a lot like mine, but there were some cool ideas that I would never have thought of, (and some that were over my head, too)

This is what I did:

``````function convertToRoman(num) {
function roman(n){
switch(n){
case 0:
return ['I','II','III','IV','V','VI','VII','VIII','IX'];
break;
case 1:
return ['X','XX','XXX','XL','L','LX','LXX','LXXX','XC'];
break;
case 2:
return ['C','CC','CCC','CD','D','DC','DCC','DCCC','CM'];
break;
case 3:
return ['M','MM','MMM','MMMM'];
break;
}
}

let arr = num.toString().split('');
// console.log(arr);
let newArr = [];
for ( let i=0; arr.length>0; i++ ) {
let n = arr.pop();
let place = roman(i);
//console.log(parseInt(n));
if ( parseInt(n) > 0 ) {
newArr.push(place[parseInt(n)-1]);
}
}
let str = '';
while ( newArr.length>0 ){
str += newArr.pop();
}
return str;
}

convertToRoman(36);
``````