Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Trevor Johnson
Trevor Johnson
14,427 Points

JS Help With a For Loop

Hey there, I am having some trouble with this challenge on FCC. All I have to do is convert a number into a roman numeral. Right now I am trying to break the challenge down and do it in smaller chunks, and move my way up to be able to convert larger numbers. I am able to convert numbers 1-10, but as soon as I get above 10 my output gets funky, and I am not sure why. I would appreciate any feedback on why my loop isn't correctly outputting numbers larger than 10.

Directions:

Convert the given number into a roman numeral.

function convertToRoman(num) {
  var decimalValue = [1, 4, 5, 9, 10], //40, 50, 90, 100, 400, 500, 900, 1000],
      romanNumeral = ['I', 'IV', 'V', 'IX', 'X'], //'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'],
      romanized = '',
      newArr = [],
      reverseNum = num.toString().split('').reverse().join('');


  for (i = 0; i < reverseNum.length; i ++) {
    var power = Math.pow(10, i);
    var newNumb = power * reverseNum[i];
    var zero = 0;
    for (j = 0; j < decimalValue.length; j ++) {
      var subtract = 0;
      if (newNumb == decimalValue[j]) { 
        romanized += romanNumeral[j];
      } else if (reverseNum[i] === '0') {
        zero += 1;
      }

      else if (newNumb < decimalValue[j]) {
        subtract = reverseNum - decimalValue[j - 1];
        romanized = romanNumeral[j - 1];
        for (k = 0; k < subtract; k ++) {
          romanized += romanNumeral[0];
        }
        break;
      } 
    }
  }

return romanized;

}

convertToRoman(2);

1 Answer

Steven Parker
Steven Parker
231,271 Points

This seems really complicated.

I'm not quite following the logic at first glance, but it seems like it shouldn't be so complicated. And I'm totally lost about reversing the number.

Wouldn't all you need to do be loop while subtracting the value of the largest decimalValue that will fit, while collecting the corresponding romanNumeral at the same time until the value reaches 0?

Steven Parker
Steven Parker
231,271 Points

Just to prove it to myself I coded it. I don't want to spoil your challenge but it took 11 lines of code.

So what's FCC?

Trevor Johnson
Trevor Johnson
14,427 Points

FCC is freecodecamp.com. It's a great site for learning JavaScript

Trevor Johnson
Trevor Johnson
14,427 Points

I am reversing the number to multiply each digit by its corresponding 10s value. So if my input is 123, I want to multiply 3 * 10^0, 2 * 10^1, and 1 * 10^2 so that I can try and match a value from the roman numeral array

Steven Parker
Steven Parker
231,271 Points

I still don't understand all the multiplication and exponent stuff. Maybe there is a way to do it using that, but I can tell you that the solution I coded is very simple and uses only subtraction.

Trevor Johnson
Trevor Johnson
14,427 Points

It's ok. Let's forget about my code. I could use some help because I have spent a lot of time on this and nothing has clicked.

Trevor Johnson
Trevor Johnson
14,427 Points

I would appreciate it if you could elaborate just a little more on your hint in first comment. It didn't make much sense to me.

Trevor Johnson
Trevor Johnson
14,427 Points

I figured it out. Let's see how you did it.

function convertToRoman(num) {
var number = [ 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 ],
    roman = [ 'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I' ],
    newArr = [],
    newNum = num.toString().split('').reverse(),
    subtract = 0;


  if (number.indexOf(num) > -1) {
   newArr.unshift(roman[number.indexOf(num)]);
 } else {
   for (a = 0; a < newNum.length; a ++) {
     if (newNum[a] < 4) {
       for (i = 0; i < newNum[a]; i ++) {
         newArr.unshift(roman[number.indexOf(number[12] * Math.pow(10, a))]);
       } 
     } else if (newNum[a] > 5 && newNum[a] < 9) {
       subtract = newNum[a] - 5;
       for (j = 0; j < subtract; j ++) {
         newArr.unshift(roman[number.indexOf(number[12] * Math.pow(10, a))]);
       }
       newArr.unshift(roman[number.indexOf(number[10] * Math.pow(10, a))]);
     } else if (number.indexOf(parseInt(newNum[a])) > -1) {
         newArr.unshift(roman[number.indexOf(parseInt(newNum[a]) * Math.pow(10, a))]);
     } else {
         if (newNum[a] === 0) {
         newArr.unshift('');     
       } 
     }
   }   
 }

  return newArr.join('');

}

convertToRoman(44);
Steven Parker
Steven Parker
231,271 Points

Wow, good job. :+1: I'd have to spend some time with that to understand it!

Here's my mathematically simple approach:

function romanize(num) {
  var decimal = [1000,900,500, 400,100,  90, 50, 40,  10,   9,  5,   4,  1 ],
      numeral = [ 'M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'],
      roman = '';

  while (num > 0) {
    for (var i = 0; i < decimal.length; i++) {
      if (num >= decimal[i]) {
        roman += numeral[i];
        num -= decimal[i];
        break;
      }
    }   
  }
  return roman;
}
Trevor Johnson
Trevor Johnson
14,427 Points

How does the break statement work in your code? Does it break out of the if statement and then repeat the for loop until num = 0?

Steven Parker
Steven Parker
231,271 Points

The for loop finds the next roman numeral (or pair). When found, the break statement ends the for loop so the while loop can continue the process and find the rest.