Roman Numeral Converter Challenge

So I just solved the Roman Numeral Converter Challenge but my code comes across as not super clean and I’m curious to see how other people solved the challenge and if they were able to do it more efficiently than me. Here is my code:

`

I would love to see/hear how other people went about the challenge and if people think my solution is way too hacky and just get other perspectives!

3 Likes

Yours looks similar to mine (although mine no longer solves the challenge since they changed it–i should probably refactor it) I don’t remember who’s it was, but I saw someone who had put the roman characters in a 1D array and used a simple math expression to assemble the Roman numerals from the Arabic. it was super elegant.

1 Like

Interesting to see an approach that allows you to hardcode less of the transitions. My solution is a lot shorter because I hardcode all the edges. (inspired by a conversation I had with another camper, I wasn’t clever enough to think this up alone).

function convertToRoman(num) {
  var result = "";
  var arabic = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
  var roman = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
  
  for (var i = 0; i < arabic.length; i++) {
    while(num >= arabic[i]) {
      result += roman[i];
      num -= arabic[i];
    }
  }
  
  return result;
}
26 Likes

This is how I ended up dong mine. Interesting to see the different ways people have done this.

2 Likes

This is an interesting idea - comparing completely different solutions.

2 Likes

Yea it’s awesome to see all of these different methods that I never would have thought about. I definitely want to do this with some of the other challenges in the future. Always helpful to look at how others solved a problem and compare it to your own solution.

3 Likes

Hello guys. I just did mine and I was excited to see once again it is different than all the other varied approaches. I do not know enough to know which is more efficient or not, I guess the less code you have the better it is in which case it is not the best, but it works!

Yeah, it’s great to see just how many approaches there are to solving the same problem! You can do this on CodeWars. When you solve a problem, you can see how everyone else did it and you get to see some really elegant solutions. I highly recommend it just for that.

This is how I did the roman numerals.

2 Likes

I like the one you posted. Short and simple!

1 Like

that is how i’ve done the challenge :slight_smile:

2 Likes

This is how I did for the roman numeral converter.

function convertToRoman(num) {
  var roman = {M:1000,D:500,C:100,L:50,X:10,V:5,I:1};
  var number = num;
  var priorKey = 0;
  var romanNum = "";

  for (var key in roman) {
    d = Math.floor(number/roman[key]);
    if (d===0) {
      priorKey = key;
    } else if (d<4) {
      for (var j=0; j<d; j++) romanNum += key;
      number = number - d*roman[key];
      if (roman[key].toString()[0]!="5") priorKey = key;
    } else if (d===4) {
      if (roman[priorKey].toString()[0]==="1") {
        romanNum = romanNum.slice(0,-1);
      }
      romanNum += key + priorKey;
      number = number - d*roman[key];
      priorKey = key;
    }
  }
  return romanNum;
}
1 Like

I like this. A little bit of hardcoding is totally worth enough only to require a code that is very simple and short.

Not knowing my way around the Roman numeral system very well, I went for an approach that was heavy on hard coding. “Elegant” solutions will use more processor power while hard coded solutions will use more memory. However, any reasonable solution for this is not going to tax the processor or memory of a modern desktop or laptop.

function convertToRoman(num) {

var numTrack = num;
var tensIndex = [];
var romanStr = “”;

tensIndex.push(Math.floor(numTrack/1000));
numTrack -= tensIndex[0] * 1000;
tensIndex.push(Math.floor(numTrack/100));
numTrack -= tensIndex[1] * 100;
tensIndex.push(Math.floor(numTrack/10));
numTrack -= tensIndex[2] * 10;
tensIndex.push(Math.floor(numTrack/1));

for (i=0; i<tensIndex[0]; i++) {
romanStr += “M”;
}

switch(tensIndex[1]) {
case 0:
break;
case 1:
romanStr += “C”;
break;
case 2:
romanStr += “CC”;
break;
case 3:
romanStr += “CCC”;
break;
case 4:
romanStr += “CD”;
break;
case 5:
romanStr += “D”;
break;
case 6:
romanStr += “DC”;
break;
case 7:
romanStr += “DCC”;
break;
case 8:
romanStr += “DCCC”;
break;
case 9:
romanStr += “CM”;
break;
}

switch(tensIndex[2]) {
case 0:
break;
case 1:
romanStr += “X”;
break;
case 2:
romanStr += “XX”;
break;
case 3:
romanStr += “XXX”;
break;
case 4:
romanStr += “XL”;
break;
case 5:
romanStr += “L”;
break;
case 6:
romanStr += “LX”;
break;
case 7:
romanStr += “LXX”;
break;
case 8:
romanStr += “LXXX”;
break;
case 9:
romanStr += “XC”;
break;
}

switch(tensIndex[3]) {
case 0:
break;
case 1:
romanStr += “I”;
break;
case 2:
romanStr += “II”;
break;
case 3:
romanStr += “III”;
break;
case 4:
romanStr += “IV”;
break;
case 5:
romanStr += “V”;
break;
case 6:
romanStr += “VI”;
break;
case 7:
romanStr += “VII”;
break;
case 8:
romanStr += “VIII”;
break;
case 9:
romanStr += “IX”;
break;
}

return romanStr;
}

1 Like

Tried to solve this with a reduce function. Here is my solution:

1 Like

It seems that this challenge’s test conditions since I originally finished it last year, so my solution no longer worked. I made a new one for fun and profit. There are some really awesome solutions here!

function translateNumbers(numberObj) {
    var result = "";
    if(numberObj.arabic === 9) {
        result += numberObj.nine;
    } else if(numberObj.arabic >= 5) {
        result += numberObj.five;
        for(var i = (numberObj.arabic - 5); i > 0; i--) {
            result += numberObj.one;
        }
    } else if(numberObj.arabic === 4) {
        result += numberObj.four;
    } else {
        for(var i = numberObj.arabic; i > 0; i--) {
            result += numberObj.one;
        }
    }
    return result;
}

function convertToRoman(num) {
    var thousands = Math.floor(num/1000),
        hundreds = Math.floor((num % 1000)/100),
        tens = Math.floor((num % 100)/10),
        ones = num % 10,
        romanString = "",
        numbers = [
            {
                arabic: hundreds,
                nine: "CM",
                five: "D",
                four: "CD",
                one: "C"
            },
            {
                arabic: tens,
                nine: "XC",
                five: "L",
                four: "XL",
                one: "X"
            },
            {
                arabic: ones,
                nine: "IX",
                five: "V",
                four: "IV",
                one: "I"
            }
        ];

    //thousands edgecase - **THANKS ROMANIA! :P**
    while(thousands) {
        romanString += "M";
        thousands--;
    }

    numbers.forEach(function(numberObj) {
        romanString += translateNumbers(numberObj);
    });

 return romanString;
}

convertToRoman(1987);
2 Likes

The same thing happened to me with several of the challenges being changed. I’ve actually enjoyed going back and changing them for extra practice. Although this is one I haven’t gotten to yet.

1 Like

Not so elegant

        function convertToRoman(num) {
               var n_M = Math.floor(num/1000);
               var n_D =  Math.floor((num-n_M*1000)/500);
               var n_C =  Math.floor((num-n_M*1000-n_D*500)/100); 
               var n_L =  Math.floor((num-n_M*1000-n_D*500-n_C*100)/50);
               var n_X =  Math.floor((num-n_M*1000-n_D*500-n_C*100-n_L*50)/10);
               var n_V =  Math.floor((num-n_M*1000-n_D*500-n_C*100-n_L*50-n_X*10)/5);
               var n_I =  Math.floor(num-n_M*1000-n_D*500-n_C*100-n_L*50-n_X*10-n_V*5); 
         
         var arr = [];
         //pushing Ms
         for (var i=0; i<n_M; i++) {
           arr.push("M");
         }
         //pushing Ds and Cs
         if (n_D>0 && n_C<4) {
           arr.push("D");
           for (var i=0; i<n_C; i++) {
           arr.push("C");
         }}
         else if (n_D>0 && n_C==4) {arr.push("CM");}
         else if (n_D===0 && n_C==4) {arr.push("CD");}
         else {
           for (var i=0; i<n_C; i++) {
           arr.push("C");
         }  
         }
         //pushing Ls and Xs
         if (n_L>0 && n_X<4) {
           arr.push("L");
           for (var i=0; i<n_X; i++) {
           arr.push("X");
         }}
         else if (n_L>0 && n_X==4) {arr.push("XC");}
         else if (n_L===0 && n_X==4) {arr.push("XL");}
         else {
           for (var i=0; i<n_X; i++) {
           arr.push("X");
         }  
         }
         //pushing Vs and Is
         if (n_V>0 && n_I<4) {
           arr.push("V");
           for (var i=0; i<n_I; i++) {
           arr.push("I");
         }}
         else if (n_V>0 && n_I==4) {arr.push("IX");}
         else if (n_V===0 && n_I==4) {arr.push("IV");}
         else {
           for (var i=0; i<n_I; i++) {
           arr.push("I");
         }  
         } 
         console.log(arr.join());
          return arr.join("");
        }

That’s a great solution P1xt, very clever! Mine is way to long and complicated to even show here.

Hi there, here is what I came up with.

function convertToRoman(num) {
var numA = num.toString().split(“”);

var r1 = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"];
var r2 = ["", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"];
var r3 = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"];
var r4 = ["", "M", "MM", "MMM"];
if (numA.length == 1) {
    return r1[numA];
} else if (numA.length == 2) {
    //console.log("2 digits: " + numA + " | " + r2[numA[0]]);
    return r2[numA[0]] + r1[numA[1]];
} else if (numA.length == 3) {
    return r3[numA[0]] + r2[numA[1]] + r1[numA[2]];
} else if (numA.length == 4) {
    return r4[numA[0]] + r3[numA[1]] + r2[numA[2]] + r1[numA[3]];
}

}

convertToRoman(36);

3 Likes

`` function convertToRoman(num) {

//Check for the units 
UnitsRoman = ["I","II","III","IV","V","VI","VII", "VIII", "IX"];
UnitsNorm = ["1","2","3","4","5","6","7", "8", "9"];

TensRoman = ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"];
TensNorm = ["10", "20", "30", "40", "50", "60", "70", "80", "90"];

HundredsRoman = ["C", "CC", "CCC", "CD","D", "DC", "DCC", "DCCC", "CM"];
HundredsNorm = ["100", "200", "300", "400","500", "600", "700", "800", "900"];

ThousandRoman = ["M", "MM", "MMM", "","D", "DC", "DCC", "DCCC", "CM"];
ThousandNorm = ["1000", "2000", "3000", "400","500", "600", "700", "800", "900"];


var newNum;

arrNum = num.toString();
arrNum = arrNum.split("");
console.log(arrNum.length);


switch (arrNum.length){
	case 1:
		newNum = UnitsRoman[UnitsNorm.indexOf(arrNum[0])];
		break;
		
	case 2:
		if(arrNum[1] === "0"){
			newNum = TensRoman[UnitsNorm.indexOf(arrNum[0])]
		}else{
			newNum = TensRoman[UnitsNorm.indexOf(arrNum[0])] + UnitsRoman[UnitsNorm.indexOf (arrNum[1])];
		}
		break;
	case 3:
		if(arrNum[2] === "0" && arrNum[1] === "0"){
			newNum = HundredsRoman[UnitsNorm.indexOf(arrNum[0])];
		}
		else if(arrNum[1] === "0"){
			newNum = HundredsRoman[UnitsNorm.indexOf(arrNum[0])] + UnitsRoman[UnitsNorm.indexOf(arrNum[2])];
		}
		else{
			newNum = HundredsRoman[UnitsNorm.indexOf(arrNum[0])] + TensRoman[UnitsNorm.indexOf(arrNum[1])] + UnitsRoman[UnitsNorm.indexOf (arrNum[2])];
			}
		break;
		
	case 4:
		//1       0                    0                    0
		if(arrNum[1] === "0" && arrNum[2] === "0" && arrNum[3] === "0"){
			newNum = ThousandRoman[UnitsNorm.indexOf(arrNum[0])];
		}
		//1            0                    0                   1-9
		else if(arrNum[1] === "0" && arrNum[2] === "0" && arrNum[3] != "0"){
			newNum = ThousandRoman[UnitsNorm.indexOf(arrNum[0])] + UnitsRoman[UnitsNorm.indexOf (arrNum[3])];
		}
		//1            0                    1                   6
		else if(arrNum[1] === "0" && arrNum[2] != "0" && arrNum[3] != "0"){
			newNum = ThousandRoman[UnitsNorm.indexOf(arrNum[0])] + TensRoman[UnitsNorm.indexOf(arrNum[2])] + UnitsRoman[UnitsNorm.indexOf (arrNum[3])] ;
		}
		else{
			newNum = ThousandRoman[UnitsNorm.indexOf(arrNum[0])] + HundredsRoman[UnitsNorm.indexOf(arrNum[1])] + TensRoman[UnitsNorm.indexOf (arrNum[2])] + UnitsRoman[UnitsNorm.indexOf (arrNum[3])];
		}
		break;
}
return newNum;