0

I'm working through the intermediate algorithms in the FreeCodeCamp curriculum. One of them involves converting integers to roman numerals. My solution (presented below) works, however it is very much the "naive" approach, if you will. The task hints that array.splice(), array.indexOf(), and array.join() ought to be used. My implementation only uses array.join().

Edited question for precision: Will someone provide an implementation that makes use of all of the aforementioned methods?

Thanks.

My implementation:

function convertToRoman(num) {
  var I = 1, V = 5, X = 10, L = 50, C = 100, D = 500, M = 1000;
  var numerals = [];
  var i;

  if(num >= 1000){
    var numMs =  Math.floor(num / 1000);
    for (i = 0; i < numMs; i++){
      numerals.push('M');
    }
    num = num % 1000; 
  }

  if(num >= 900){
    numerals.push('CM');
    num = num - 900;
  }

  if(num < 900){
    if(num >= 500){
      numerals.push('D');
      num = num - 500;
    }
    if(num >= 400){
      numerals.push('CD');
      num = num - 400;
    }
    var numCs = Math.floor(num / 100);
    for(i = 0; i < numCs; i++){
      numerals.push('C');
    }
    num = num % 100;
  }

  if(num >= 90){
    numerals.push('XC');
    num = num - 90;
  }

  if(num < 90){
    if(num >= 50){
      numerals.push('L');
      num = num - 50;
    }
    if(num >= 40){
      numerals.push('XL');
      num = num - 40;
    }
    var numXs = Math.floor(num / 10);
    for(i = 0; i < numXs; i++){
      numerals.push('X');
    }
    num = num % 10;
  }

  if(num == 9){
    numerals.push('IX');
    num = num - 9;
  } 

  if(num < 9){
    if(num >= 5){
      numerals.push('V');
      num = num - 5;
    }
    if(num >=4){
      numerals.push('IV');
      num = num - 4;
    }
    var numIs = Math.floor(num / 1);
    for(i = 0; i < numIs; i++){
      numerals.push('I');
    }
  }

  var converted = numerals.join('');

  return converted;
} 

UPDATE: Another answer found here, but it does not use the methods I'm interested in using.

Community
  • 1
  • 1
vince
  • 7,808
  • 3
  • 34
  • 41
  • [**If you search, you will find...**](http://stackoverflow.com/questions/9083037/convert-a-number-into-a-roman-numeral-in-javascript) – adeneo Oct 25 '16 at 17:02
  • I can even come up with a way which *doesn't* use any of the above mentioned functions – Bálint Oct 25 '16 at 17:02
  • @adeneo I saw that, it doesn't use the methods I'm looking to use. – vince Oct 25 '16 at 17:03
  • The answer to the question you've actually asked, obviously, is **yes**.... The point I'm making, is that perhaps a better question could be found to bridge the gap between where you are and would like to be. – enhzflep Oct 25 '16 at 17:24
  • Understood @enhzflep, I've edited the question to be more precise. I'm new to this and greatly appreciate your advice. – vince Oct 25 '16 at 21:02

2 Answers2

1

You may do as follows;

function toRoman(n){
  var numerals = ["I","V","X","L","C","D","M"];
  return n.toString()
          .split("")
          .reverse()
          .reduce((p,c,i) => (c === "0" ? ""
                                        : c < "4" ? numerals[2*i].repeat(c)
                                                  : c === "4" ? numerals[2*i] + numerals[2*i+1]
                                                              : c < "9" ? numerals[2*i+1] + numerals[2*i].repeat(c-5)
                                                                        : numerals[2*i] + numerals[2*i+2]) + p,"");
}
console.log(toRoman(1453));
Redu
  • 25,060
  • 6
  • 56
  • 76
1

This is a proposal which use Array#reduce for any part of the number to convert.

function toRoman(i) {
    return ('0000' + i).slice(-4).split('').map(Number).reduce(function (r, a, i) {
        var value = 'MDCLXVI';
        if (a === 4 || a === 9) {
            r += value[i * 2];
            a++;
        }
        if (a === 10) {
            r += value[i * 2 - 2];
            a -= 10;
        }
        if (a >= 5) {
            r += value[i * 2 - 1];
            a -= 5;
        }
        while (a) {
            r += value[i * 2];
            a--;
        }
        return r;
    }, '');
}

var i;
for (i = 1; i <= 3000; i++) {
    document.getElementById('tt').innerHTML += i + ' ' + toRoman(i) + `\n`;
}
<pre id="tt"></pre>
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392