Post your Roman Numeral Converter solutions here! (Fall 2022)

Your thought process is absolutely correct.
However,
for 36 = 30 * 10 + 6 * 1
You should code the
secondTStageRN = remainder1 * 1

You get an error becuse whole1 * X , and X is not defined anywhere in your code. And to get 6 you should not use whole1, but remainder1 * 1

Hope this is clear.

4 Likes

Woohoo keep going. with @cpucortexm2924547 's extra hints you may get there. The vid will also definitely help but I love how you dived into this trying to sort out how it works first on your own. Coders are problem solvers in the first place, and you got to understand the problem to be able to solve it (and find edge cases to deal with). You are definitely on the right track! Keep going!

2 Likes

Hello,

I am really stuck on this and I am trying to come up a with a solution I can understand… I am trying to get a loop to iterate though the roman object and print out with roman equivalent of the number (object property). What’s the logic to have this done? This is my code so far and yes, I am really far from having a solution.

function convertToRoman(num) {
 var chart = {
   M: 1000, 
   CM: 900, 
   D: 500, 
   CD: 400, 
   C: 100, 
   XC: 90, 
   L: 50, 
   XL: 40, 
   X: 10, 
 }

let str = "";

for (let i = 1; i <= 1000; i++) {
    if (num ===  Object.values(chart)[i]) {
      str = 
    }
  }
   return str
}
1 Like

Hi Damien,

Thinking through a problem and trying to figure out what needs to be done to solve it is the core of our job as programmer. So this is a good start (any start is better than none!)

Avoid using ‘var’. It is not wrong and you will find it in pre-ES6 code, but you should largely treat it as a thing of the past and declare variables with let/const.

Your code is doing 3 things:

  • defines a roman object called ‘chart’
  • implements a for loop with a random stop value of 1000 for index i (I mean I do not understand why you chose that)
  • compares the input argument num with an return value for the index (if it exists, which is mostly not true)

So let’s have a closer look. Did you try a console log to see what your loop does return for your object value?

function convertToRoman(num) {
 const chart = {
   M: 1000, 
   CM: 900, 
   D: 500, 
   CD: 400, 
   C: 100, 
   XC: 90, 
   L: 50, 
   XL: 40, 
   X: 10, 
 }

  for (let i = 1; i <= 10; i++) {
      console.log(Object.values(chart)[i])
  }

}

As you can see I reduced the index to be smaller or equal to 10 and my output is

900
500
400
100
90
50
40
10
undefined
undefined

That should give you already a clue on why this approach is not working. It loops through your object and simply returns the value for each index, and you have only 9 of them. Then you compare the returned value (for each of these values) with the number passed into the function. What is the chance someone asks for exactly 500 to be converted, rather than 2022? So this approach is not very robust.

So you need to restrict your look up to the length of your object, and you do need to gain access to the the key value (you could swap your key and value, so you can look up the number using the key and retrieve the value). In Rotimi’s answer here (Post your Roman Numeral Converter solutions here! (Fall 2022) - #5 by Timiphil) the loop is through all elements in the object and return the key (the variable is named i, but it is not really an index but rather the key).

Then also you need to think in how to process the problem. Solutions that are posted in this thread show different approaches. You could find the number of thousands, hundreds, etc and try to match your answer there. Or reduce the value with the largest amount (if possible) and balance it out with the matching character in the result.

Does this help in any way to develop an approach?

3 Likes

My Solution, no the best, but i do it.

function roman1to10(num){
    const romanUnity = ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"];
    if (num!=0){
        let romano = romanUnity[num-1];
        return romano;
    } else return "";
}

function roman11to100(num){
    const romanDecena = ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "C"];
    if (num!=0){
        let romano = romanDecena[num-1];
        return romano;
    } else return "";
}

function roman101to1000(num){
    const romanCentena = ["C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "M"];
    if (num!=0){
        let romano = romanCentena[num-1];
        return romano;
    } else return "";
}

function roman1001to3999(num){
    const romanMil = ["M", "MM", "MMM"];
    if (num!=0){
        let romano = romanMil[num-1];
        return romano;
    } else return "";
}

function convertToRoman(num) {  
  let strNum = num.toString();
  const numArray = strNum.split("");
  console.log(numArray)
  let romano = "";
  if (numArray.length == 1){
     romano = roman1to10(numArray[0]);
     return romano;
      
  } else if (numArray.length == 2){
    romano = roman11to100(numArray[0]);
    romano += roman1to10(numArray[1]);
    return romano;
    
    } else if (numArray.length == 3){
    romano = roman101to1000(numArray[0]);
    romano += roman11to100(numArray[1]);
    romano += roman1to10(numArray[2]);
    return romano;
    
    } else if (numArray.length == 4){
    romano = roman1001to3999(numArray[0]);
    romano += roman101to1000(numArray[1]);
    romano += roman11to100(numArray[2]);
    romano += roman1to10(numArray[3]);
    return romano;
    
    }
        
}
3 Likes

Here is my solution to Roman Numeral Converter.
Cheers, T.

const RomanArabicMapping = {
  M: 1000,
  CM: 900,
  D: 500,
  CD: 400,
  C: 100,
  XC: 90,
  L: 50,
  XL: 40,
  X: 10,
  IX: 9,
  V: 5,
  IV: 4,
  I: 1,
};


const convertToRoman = number => {
  let strRoman = "";

  // Loop through all the Object Properties
  for (const keyRoman in RomanArabicMapping) {
    // Construct the Roman numeral for the current Key
    while (number >= RomanArabicMapping[keyRoman]) {
      strRoman += keyRoman;
      number -= RomanArabicMapping[keyRoman];
    }
  }

  // Take care of "0" being passed
  return (strRoman === "" ? "Unknown" : strRoman);
}

console.log(convertToRoman(2)); //should return the string II.
console.log(convertToRoman(3)); //should return the string III.
console.log(convertToRoman(4)); //should return the string IV.
console.log(convertToRoman(5)); //should return the string V.
console.log(convertToRoman(9)); //should return the string IX.
console.log(convertToRoman(12)); //should return the string XII.
console.log(convertToRoman(16)); //should return the string XVI.
console.log(convertToRoman(29)); //should return the string XXIX.
console.log(convertToRoman(44)); //should return the string XLIV.
console.log(convertToRoman(45)); //should return the string XLV.
console.log(convertToRoman(68)); //should return the string LXVIII
console.log(convertToRoman(83)); //should return the string LXXXIII
console.log(convertToRoman(97)); //should return the string XCVII
console.log(convertToRoman(99)); //should return the string XCIX
console.log(convertToRoman(400)); //should return the string CD
console.log(convertToRoman(500)); //should return the string D
console.log(convertToRoman(501)); //should return the string DI
console.log(convertToRoman(649)); //should return the string DCXLIX
console.log(convertToRoman(798)); //should return the string DCCXCVIII
console.log(convertToRoman(891)); //should return the string DCCCXCI
console.log(convertToRoman(1000)); //should return the string M
console.log(convertToRoman(1004)); //should return the string MIV
console.log(convertToRoman(1006)); //should return the string MVI
console.log(convertToRoman(1023)); //should return the string MXXIII
console.log(convertToRoman(2014)); //should return the string MMXIV
console.log(convertToRoman(3999)); //should return the string MMMCMXCIX
3 Likes

Started step by step and after many tries this worked:

function convertToRoman(num) {
 var romanNumbers = {
    M:1000,
    CM:900,
    D:500,
    CD:400,
    C:100,
    XC:90,
    L:50,
    XL:40,
    X:10,
    IX:9,
    V:5,
    IV:4,
    I:1
  };

   var romanized = "";
   for(var key in romanNumbers){
     var numberValue = romanNumbers[key];
     while(numberValue <= num){
       num-=numberValue;
       romanized+=key;
     }
   }
   return romanized;
}
var result=convertToRoman(666);
console.log(result);

But a little unsure when to use Var or Const, in this case it went fine with vars,

3 Likes

Love it!

If I may suggest, using the following:

If the value will be reassigned, use let.
If it won’t, use const.

I don’t use var

2 Likes

Here is my slow-poke code, done before class where Ramon showed us how to re-factor the code more efficiently:

function convertToRoman(num) {
if (num <= 0) return ‘error’;

let result = ‘’;
let remaining = num;

if (num >= 1000) {
for (let i = 0; i < Math.floor(num / 1000); i++) {
result += ‘M’;
}
remaining = num % 1000;
}

if (remaining >= 900) {
result += ‘CM’;
remaining -= 900;
}

if (remaining >= 500) {
result += ‘D’;
remaining -= 500;
}

if (remaining >= 400) {
result += ‘CD’;
remaining -= 400;
}

if (remaining >= 100) {
for (let i = 0; i < Math.floor(remaining / 100); i++) {
result += ‘C’;
}
remaining = remaining % 100;
}

if (remaining >= 90) {
result += ‘XC’;
remaining -= 90;
}

if (remaining >= 50) {
result += ‘L’;
remaining -= 50;
}

if (remaining >= 40) {
result += ‘XL’;
remaining -= 40;
}

if (remaining >= 10) {
for (let i = 0; i < Math.floor(remaining / 10); i++) {
result += ‘X’;
}
remaining = remaining % 10;
}

if (remaining >= 9) {
result += ‘IX’;
remaining -= 9;
}

if (remaining >= 5) {
result += ‘V’;
remaining -= 5;
}

if (remaining >= 4) {
result += ‘IV’;
remaining -= 4;
}

if (remaining >= 1) {
for (let i = 0; i < remaining; i++) {
result += ‘I’;
}
remaining = 0;
}

if (remaining != 0) return ‘error’;

return result;
}

convertToRoman(36);

console.log(convertToRoman(1798));

3 Likes

Funny, I think your thought process was similar to mine (also done before class) - only that I literally declared thousands of variables :wink:

function convertToRoman(num) {
  //break into biggest chunks and get remainders after each chunk
  //die thousands etc müssen dann noch umgewandelt werden; Achtung: strings können in javascript aber nicht multipliziert werden
  let thousands = Math.floor(num / 1000);
  let remains = num - thousands*1000;
  thousands = "M".repeat(thousands);
  let nineHundreds = Math.floor(remains / 900);
  remains -= nineHundreds*900;
  nineHundreds = "CM".repeat(nineHundreds);
  let fiveHundreds = Math.floor(remains / 500);
  remains -= fiveHundreds*500;
  fiveHundreds = "D".repeat(fiveHundreds);
  let fourHundreds = Math.floor(remains / 400);
  remains -= fourHundreds*400;
  fourHundreds = "CD".repeat(fourHundreds);
  let hundreds = Math.floor(remains / 100);
  remains -= hundreds*100;
  hundreds = "C".repeat(hundreds);
  let nineties = Math.floor(remains / 90);
  remains -= nineties*90;
  nineties = "XC".repeat(nineties);
  let fifties = Math.floor(remains / 50);
  remains -= fifties*50;
  fifties = "L".repeat(fifties);
  let fourties = Math.floor(remains / 40);
  remains -= fourties*40;
  fourties = "XL".repeat(fourties);
  let tens = Math.floor(remains / 10);
  remains -= tens*10;
  tens = "X".repeat(tens);
  let nines = Math.floor(remains / 9);
  remains -= nines*9;
  nines = "IX".repeat(nines);
  let fives = Math.floor(remains / 5);
  remains -= fives*5;
  fives = "V".repeat(fives);
  let fours = Math.floor(remains / 4);
  remains -= fours*4;
  fours = "IV".repeat(fours);
  let ones = Math.floor(remains / 1);
  ones = "I".repeat(ones);

  //add all of them together
  return (thousands + nineHundreds + fiveHundreds + fourHundreds + hundreds + nineties + fifties + fourties + tens + nines + fives + fours + ones);
}

console.log(convertToRoman(36));
3 Likes

That’s great Sandra! Great minds think alike. Are you also doing the Responsive Web Design boot camp, or did you already complete that one previously?

1 Like

I had the same approach, but made one helping function for all :joy:

function convertSingleToRoman(num, einheit) {
  //einheit: 0-9: 10^0, 10-99: 10^1, 101-999: 10^2 1000-3999: 10^3
    const Numerals = {
      0: "",
      1: "I",
      5: "V",
      10: "X",
      50: "L",
      100: "C",
      500: "D",
      1000: "M"
    }
    switch (num) {
      case '0':
        return Numerals[0];;
      case '1':
        return Numerals[einheit];
      case '2':
        return Numerals[einheit] + Numerals[einheit];
      case '3':
        return Numerals[einheit] + Numerals[einheit] + Numerals[einheit];
      case '4':
        return Numerals[einheit] + Numerals[5 * einheit];
      case '5':
        return Numerals[5 * einheit];
      case '6':
        return Numerals[5 * einheit] + Numerals[einheit];
      case '7':
        return Numerals[5 * einheit] + Numerals[einheit] + Numerals[einheit];
      case '8':
        return Numerals[5 * einheit] + Numerals[einheit] + Numerals[einheit] + Numerals[einheit];
      case '9': 
        return Numerals[einheit] + Numerals[10 * einheit];
      default:
        return false;
    }
  }

function convertToRoman(num) {
  let digitArray = num.toString().split("");
  for (let index in digitArray) {
    digitArray[index] = convertSingleToRoman(digitArray[index], Math.pow(10, digitArray.length - 1 - index));
  }
  return digitArray.join("");
}
3 Likes

Yes, I’m also doing the Web Design bootcamp (although I have already done a little bit of HTML and CSS ages ago (pre-HTML5 ;-))

1 Like

function convertToRoman(num) {
//declare lookup variable with object property key/value pairs
let lookup = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
V: 5,
IV: 4,
I: 1
},
//declare for loop and while condition; set increment and decrement
romanNum = “”, x;
for (x in lookup) {
while(num >= lookup){
romanNum += x;
num -= lookup;
}
}
//return roman numeral
return romanNum;
}
console.log(convertToRoman(36));

4 Likes

Here is my attempt using the switch case statement and a double array.

function convertToRoman(num) {
  if (num >= 4000 || num <= 0) { 
    return 'Converter is limited to numbers below 4000';
  } else if (/\D/.test(num)) {
    return 'Input includes non digit characters'
  }

  const romanSymbol = [['I','IV','V','IX'],['X','XL','L','XC'],['C','CD','D','CM'],['M']];

  const arrNum = num.toString().match(/\d/g).reverse();
  console.log(arrNum);
  const arrRoman = []; // Declare array to build Roman Number
  for(let i=0; i<arrNum.length; i++){
    switch (arrNum[i]){
      case '0':
        break;
      case '9':
        arrRoman.unshift(romanSymbol[i][3]);
        break;
      case '8':
        arrRoman.unshift(romanSymbol[i][0]);
      case '7':
        arrRoman.unshift(romanSymbol[i][0]);
      case '6':
        arrRoman.unshift(romanSymbol[i][0]);
      case '5':
        arrRoman.unshift(romanSymbol[i][2]);
        break;
      case '4':
        arrRoman.unshift(romanSymbol[i][1]);
        break;
      case '3':
        arrRoman.unshift(romanSymbol[i][0]);
      case '2':
        arrRoman.unshift(romanSymbol[i][0]);
      case '1':
        arrRoman.unshift(romanSymbol[i][0]);
      break;
    }
  }
  return num = arrRoman.join('');
}

console.log(convertToRoman(3948 ))
3 Likes

Here is a shorter version using class, and lookup.

const lookup = {'M': 1000, 'CM': 900, 'D': 500, 'CD':400, 'C': 100, 'XC': 90, 'L': 50, 'XL': 40, 'X': 10, 'IX': 9, 'V': 5, 'IV': 4, 'I': 1}

class NumeralConverter {
  constructor(number){
    this.number = number;
    this.result = '';
  }
  processNumeral(symbol, symbolValue) {
    while (this.number >= symbolValue) {
      this.result += symbol;
      this.number -= symbolValue;
    }
  }
}


function convertToRoman(num) {
  let converter = new NumeralConverter(num);
  for (const roman in lookup) {
    converter.processNumeral(roman, lookup[roman]);
  }
  return converter.result;
}


console.log(convertToRoman(2893));
3 Likes

Here is my solution. Comments are highly welcome.
const convertToRoman = num => {
let lookUpTable= {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1
};
let result = ‘’;
for (const[romanNumeral,arabicNumeral] of Object.entries(lookUpTable)){
while (num >= arabicNumeral){
result += romanNumeral;
num -= arabicNumeral;
}
}
return result;
};

console.log(convertToRoman(83)); // should log LXXXIII

3 Likes

Wooow, there are so many ways to Rom…an Numerals!
This is my solution without having watched the video.

function convertToRoman(num) {
  let romanNum = [];

  while (num != 0) {
    if (num >= 1000) {
      romanNum.push("M");
      num -= 1000;
    } else if (num >= 900){
      romanNum.push("CM");
      num -= 900;
    } else if (num >= 500){
      romanNum.push("D");
      num -= 500;
    } else if (num >= 400){
      romanNum.push("CD");
      num -= 400;
    } else if (num >= 100){
      romanNum.push("C");
      num -= 100;
    } else if (num >= 90){
      romanNum.push("XC");
      num -= 90;
    } else if (num >= 50){
      romanNum.push("L");
      num -= 50;
    } else if (num >= 40){
      romanNum.push("XL");
      num -= 40;
    } else if (num >= 10){
      romanNum.push("X");
      num -= 10;
    } else if (num >= 9){
      romanNum.push("IX");
      num -= 9;
    } else if (num >= 5){
      romanNum.push("V");
      num -= 5;
    } else if (num >= 4){
      romanNum.push("IV");
      num -= 4;
    } else if (num >= 1){
      romanNum.push("I");
      num -= 1;
    } 
  }
  
  romanNum = romanNum.join("");
 return romanNum;
}

convertToRoman(36);
3 Likes

Here is my solution. It’s not the smartest one and not even the shortest but works.

function convertToRoman(num) {

  let thousandsProto;
  let hundredsProto;
  let tensProto;
  let cipherProto;

  let thousands = "";
  let hundreds = "";
  let tens = "";
  let cipher = "";
  let numeralNumber;


  thousandsProto = Math.floor(num / 1000);

  for (let i = 0; i < thousandsProto; i++) {
    thousands += "M";
  }

  // console.log(thousandsProto);
  // console.log(thousands);

  
  hundredsProto = Math.floor((num % 1000) / 100);
  // console.log(hundredsProto);

  switch(hundredsProto) {
    case 1:
      hundreds = "C";
      break;
    case 2:
      hundreds = "CC";
      break;
    case 3:
      hundreds = "CCC";
      break;
    case 4:
      hundreds = "CD";
      break;
    case 5:
      hundreds = "D";
      break;
    case 6:
      hundreds = "DC";
      break;
    case 7:
      hundreds = "DCC";
      break;
    case 8:
      hundreds = "DCCC";
      break;
    case 9:
      hundreds = "CM";
      break;

  }

  // console.log(hundreds);


  tensProto = Math.floor((num % 100) / 10);
  // console.log(tensProto);

  switch(tensProto) {
    case 1:
      tens = "X";
      break;
    case 2:
      tens = "XX";
      break;
    case 3:
      tens = "XXX";
      break;
    case 4:
      tens = "XL";
      break;
    case 5:
      tens = "L";
      break;
    case 6:
      tens = "LX";
      break;
    case 7:
      tens = "LXX";
      break;
    case 8:
      tens = "LXXX";
      break;
    case 9:
      tens = "XC";
      break;

  }

  // console.log(tens);


  cipherProto = Math.floor(num % 10);
  // console.log(cipherProto);

  switch(cipherProto) {
      case 1:
        cipher = "I";
        break;
      case 2:
        cipher = "II";
        break;
      case 3:
        cipher = "III";
        break;
      case 4:
        cipher = "IV";
        break;
      case 5:
        cipher = "V";
        break;
      case 6:
        cipher = "VI";
        break;
      case 7:
        cipher = "VII";
        break;
      case 8:
        cipher = "VIII";
        break;
      case 9:
        cipher = "IX";
        break;

    }

    // console.log(cipher);

    numeralNumber = thousands + hundreds + tens + cipher;
    // console.log(numeralNumber);


  return numeralNumber;

}

console.log(convertToRoman(36));
console.log(convertToRoman(3457));
2 Likes

Here’s my solution. I can now see that many of the other, more efficient solutions are essentially doing the same thing as I’m doing, except instead of the copy-paste of each block in the if-else, the equivalent to the concatenation is implemented once, and objects are created to map the Roman numerals onto their specific values.

In that case, my question is: how does one gain the intuition to simplify the process in these ways? Is it just a matter of time/doing exercises/reading other people’s solutions and learning from them?

function convertToRoman(num) {
 let countDown = num;
 let romanStr = "";
 while (countDown > 0){
   if (countDown >= 1000) {
     romanStr += "M";
     countDown -= 1000;
     continue;
   } else if (countDown >= 900) {
     romanStr += ("CM");
     countDown -= 900;
     continue;
   } else if (countDown >= 500) {
     romanStr += ("D");
     countDown -= 500;
   } else if (countDown >= 400) {
     romanStr += ("CD");
     countDown -= 400;
   } else if (countDown >= 100) {
     romanStr += ("C");
     countDown -= 100;
   } else if (countDown >= 90) {
     romanStr += ("XC");
     countDown -= 90;
   } else if (countDown >= 50) {
     romanStr += ("L");
     countDown -= 50;
   } else if (countDown >= 40) {
     romanStr += ("XL");
     countDown -= 40;
   } else if (countDown >= 10) {
     romanStr += ("X");
     countDown -= 10;
   } else if (countDown >= 9) {
     romanStr += ("IX");
     countDown -= 9;
   } else if (countDown >= 5) {
     romanStr += ("V");
     countDown -= 5;
   } else if (countDown >= 4) {
     romanStr += ("IV");
     countDown -= 4;
   } else if (countDown >= 1) {
     romanStr += ("I");
     countDown -= 1;
   
   }
 }
 
 return romanStr;
}

console.log(convertToRoman(36));
1 Like