¿Cómo puedo convertir enteros en los números romanos?

function romanNumeralGenerator (int) {

}

Por ejemplo, véase el siguiente ejemplo de entradas y salidas:

1 = "I"
5 = "V"
10 = "X"
20 = "XX"
3999 = "MMMCMXCIX"

Advertencia: Sólo admiten números entre 1 y 3999

  • ¿Qué has intentado hasta ahora y por qué lo necesitas? También, este ha sido cubierta por otros idiomas. No debe ser tan difícil para convertir el código.
  • Echa un vistazo a este post, te ayudará. blog.stevenlevithan.com/archives/…
  • Algunos de los programadores de aquí probablemente podría escribir una función en cuestión de minutos. Pero, honestamente, usted debe tratar de usted mismo primero y luego preguntar si te quedas atascado.
  • número Romano convertidor
  • cualquier ayuda o una manera de comprender mejor para mí ya es algo
  • MMMIM también sería 3999

InformationsquelleAutor DD77 | 2012-01-31

58 Comentarios

  1. 81

    Hay una agradable aquí en este blog que he encontrado a través de google:

    http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

    function romanize (num) {
        if (isNaN(num))
            return NaN;
        var digits = String(+num).split(""),
            key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
                   "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
                   "","I","II","III","IV","V","VI","VII","VIII","IX"],
            roman = "",
            i = 3;
        while (i--)
            roman = (key[+digits.pop() + (i * 10)] || "") + roman;
        return Array(+digits.join("") + 1).join("M") + roman;
    }
    • Recordatorio: Esta mejor que volver NaN o tirar en lugar de devolver false como se discutió en ese post.
  2. 62
    function romanize(num) {
      var 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},roman = '',i;
      for ( i in lookup ) {
        while ( num >= lookup[i] ) {
          roman += i;
          num -= lookup[i];
        }
      }
      return roman;
    }

    Traspasados de un 2008 de comentarios que se encuentra en: http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

    VER DEMO

    • Esto es bueno, parece mentalmente fáciles de analizar lo que está sucediendo aquí. Comenzando por el número más grande, continuar restando de la tabla de búsqueda y anexando mientras que el resto es mayor que el valor de búsqueda.
    • Bueno, me tomé un micro segundo a entender, ¿qué acerca de la complejidad
    • Los objetos no tienen fin! Usted debe utilizar una matriz y evitar for...in.
    • Es bastante simple, el uso de los números más grandes hasta que no puede más, de lo contrario, intente con la siguiente más pequeña de la línea. Yo no era capaz de encontrar un método más rápido que esto. Creo que los objetos son más rápidas que las matrices en este caso. Si usted puede averiguar cómo obtener el mejor rendimiento, por favor enviar un ejemplo. Gracias por los comentarios y consejos!
    • No estoy hablando de rendimiento. Estoy diciendo que la iteración de la orden no está garantizada, por lo que el resultado puede ser completamente errónea.
    • por favor, mostrar un ejemplo de un caso donde un objeto de javascript iteración orden no estará garantizada. De lo contrario creo que son trolling
    • Yo no puedo dar un no ejemplo de trabajo, porque el orden es depende de la implementación. En su lugar, por favor, enlace a mí que parte de la especificación que se asegura que se repetirá con el orden deseado. Oh, usted no puede.
    • Podría ser una aplicación en donde no funciona. Pero hasta ahora probado que trabajan en el nodo, chrome, firefox y IE
    • los objetos no tienen ningún orden por lo que he implementado como una lista de pares [{M:1000}, ...]
    • Este es un ejemplo donde el orden de los cambios en algunos de los navegadores: for (let i in { '2': 2, '1': 1 }) console.log(i);. Además, incluso si usted la prueba, no significa que siempre funciona. Podría haber casos en que un navegador se cambia el orden por razones de rendimiento o los motivos que sean. Sólo se puede estar seguro, si conoce el código fuente de cada versión de navegador que soporte y desea apoyar en el futuro.

  3. 39

    No entiendo por qué todos la solución es tan largo y usos múltiples bucles.

    function convertToRoman(num) {
      var roman = {
        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 str = '';
    
      for (var i of Object.keys(roman)) {
        var q = Math.floor(num / roman[i]);
        num -= q * roman[i];
        str += i.repeat(q);
      }
    
      return str;
    }
  4. 13

    Estas funciones convertir cualquier número entero positivo a su equivalente en Número Romano de la cadena; y cualquier Número Romano a su número.

    Número a Número Romano:

    Number.prototype.toRoman= function () {
    var num = Math.floor(this), 
    val, s= '', i= 0, 
    v = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], 
    r = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I']; 
    function toBigRoman(n) {
    var ret = '', n1 = '', rem = n;
    while (rem > 1000) {
    var prefix = '', suffix = '', n = rem, s = '' + rem, magnitude = 1;
    while (n > 1000) {
    n /= 1000;
    magnitude *= 1000;
    prefix += '(';
    suffix += ')';
    }
    n1 = Math.floor(n);
    rem = s - (n1 * magnitude);
    ret += prefix + n1.toRoman() + suffix;
    }
    return ret + rem.toRoman();
    }
    if (this - num || num < 1) num = 0;
    if (num > 3999) return toBigRoman(num);
    while (num) {
    val = v[i];
    while (num >= val) {
    num -= val;
    s += r[i];
    }
    ++i;
    }
    return s;
    };

    Número romano de cadena a Número:

    Number.fromRoman = function (roman, accept) {
    var s = roman.toUpperCase().replace(/+/g, ''), 
    L = s.length, sum = 0, i = 0, next, val, 
    R = { M: 1000, D: 500, C: 100, L: 50, X: 10, V: 5, I: 1 };
    function fromBigRoman(rn) {
    var n = 0, x, n1, S, rx =/(\(*)([MDCLXVI]+)/g;
    while ((S = rx.exec(rn)) != null) {
    x = S[1].length;
    n1 = Number.fromRoman(S[2])
    if (isNaN(n1)) return NaN;
    if (x) n1 *= Math.pow(1000, x);
    n += n1;
    }
    return n;
    }
    if (/^[MDCLXVI)(]+$/.test(s)) {
    if (s.indexOf('(') == 0) return fromBigRoman(s);
    while (i < L) {
    val = R[s.charAt(i++)];
    next = R[s.charAt(i)] || 0;
    if (next - val > 0) val *= -1;
    sum += val;
    }
    if (accept || sum.toRoman() === s) return sum;
    }
    return NaN;
    };
  5. 13

    He desarrollado la solución recursiva a continuación. La función devuelve una letra y, a continuación, llama a sí mismo para regresar la próxima carta. Lo hace hasta que el número se pasa a la función es 0 lo que significa que todas las cartas se han encontrado y podemos salir de la recursividad.

    var romanMatrix = [
    [1000, 'M'],
    [900, 'CM'],
    [500, 'D'],
    [400, 'CD'],
    [100, 'C'],
    [90, 'XC'],
    [50, 'L'],
    [40, 'XL'],
    [10, 'X'],
    [9, 'IX'],
    [5, 'V'],
    [4, 'IV'],
    [1, 'I']
    ];
    function convertToRoman(num) {
    if (num === 0) {
    return '';
    }
    for (var i = 0; i < romanMatrix.length; i++) {
    if (num >= romanMatrix[i][0]) {
    return romanMatrix[i][1] + convertToRoman(num - romanMatrix[i][0]);
    }
    }
    }
    • Me gusta mucho tu solución. Fácil de leer, entender y muy simple. Bueno!
    • Hay demasiadas repeticiones que sucede y que es innecesario.
  6. 8

    Sé que esto es una vieja pregunta, pero estoy muy orgulloso de esta solución: a) Que se encarga únicamente de números menores que 1000, pero podría ser fácilmente ampliado para incluir no obstante grande que había necesidad de añadir al ‘numeralCodes’ matriz 2D.

    JS:

    var numeralCodes = [["","I","II","III","IV","V","VI","VII","VIII","IX"],         //Ones
    ["","X","XX","XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"],   //Tens
    ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"]];        //Hundreds
    function convert(num) {
    var numeral = "";
    var digits = num.toString().split('').reverse();
    for (var i=0; i < digits.length; i++){
    numeral = numeralCodes[i][parseInt(digits[i])] + numeral;
    }
    return numeral;  
    }

    HTML:

    <input id="text-input" type="text">
    <button id="convert-button" onClick="var n = parseInt(document.getElementById('text-input').value);document.getElementById('text-output').value = convert(n);">Convert!</button>
    <input id="text-output" style="display:block" type="text">

    • claro y elegante, buen trabajo!:-D
    • Ah esto es inteligente. Hice prácticamente lo mismo utilizando las sentencias switch, este hubiera sido mi próximo refactorizar después de averiguar el patrón y lo que es más elegante.
  7. 5

    JavaScript

    function romanize (num) {
    if (!+num)
    return false;
    var digits = String(+num).split(""),
    key = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM",
    "","X","XX","XXX","XL","L","LX","LXX","LXXX","XC",
    "","I","II","III","IV","V","VI","VII","VIII","IX"],
    roman = "",
    i = 3;
    while (i--)
    roman = (key[+digits.pop() + (i * 10)] || "") + roman;
    return Array(+digits.join("") + 1).join("M") + roman;
    }

    muchas otras sugerencias que pueden ser encontrados en la http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter

  8. 4

    Yo personalmente creo que el más bonito camino, pero no la más rápida) es con recursividad.

    function convert(num) { 
    if(num < 1){ return "";}
    if(num >= 40){ return "XL" + convert(num - 40);}
    if(num >= 10){ return "X" + convert(num - 10);}
    if(num >= 9){ return "IX" + convert(num - 9);}
    if(num >= 5){ return "V" + convert(num - 5);}
    if(num >= 4){ return "IV" + convert(num - 4);}
    if(num >= 1){ return "I" + convert(num - 1);}  
    }
    console.log(convert(39)); 
    //Output: XXXIX

    Esto sólo se admiten los números 1-40, pero fácilmente puede ser extendido mediante el siguiente patrón.

  9. 3

    De esta función es convertir cualquier número menor que 3,999,999 a la romana. Observe que los números más grandes que 3999 será dentro de una etiqueta con text-decoration conjunto para overline, esto agregará la overline que es la representación correcta para x1000 cuando el número es más grande que 3999.

    Cuatro millones (4,000,000) sería IV con dos overlines así, usted tendría que usar algún truco para representar que, tal vez una DIV con border-top, o alguna imagen de fondo con los dos overlines… Cada overline representa x1000.

    function convert(num){
    num = parseInt(num);
    if (num > 3999999) { alert('Number is too big!'); return false; }
    if (num < 1) { alert('Number is too small!'); return false; }
    var result = '',
    ref = ['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'],
    xis = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
    if (num <= 3999999 && num >= 4000) {
    num += ''; //need to convert to string for .substring()
    result = '<label style="text-decoration: overline;">'+convert(num.substring(0,num.length-3))+'</label>';
    num = num.substring(num.length-3);
    }
    for (x = 0; x < ref.length; x++){
    while(num >= xis[x]){
    result += ref[x];
    num -= xis[x];
    }
    }
    return result;
    }
    • He editado este código para permitir que los números mayores que 3,999,999. Se puede producir resultados incorrectos, aunque, a fin de utilizar con precaución. jsfiddle.net/DJDavid98/d2VEy
    • Estaba buscando esto.. gracias!!!
  10. 3

    Después de probar algunas de las implementaciones en este post, he creado una nueva optimizado para ejecutar más rápido. El tiempo de ejecución es muy baja en comparación con los demás, pero, obviamente, el código es más fea :).
    Podría ser incluso más rápido con una matriz indexada con todas las posibilidades.
    Sólo en caso de que ayude a alguien.

    function concatNumLetters(letter, num) {
    var text = "";
    for(var i=0; i<num; i++){
    text += letter;
    }
    return text;
    }
    function arabicToRomanNumber(arabic) {
    arabic = parseInt(arabic);
    var roman = "";
    if (arabic >= 1000) {
    var thousands = ~~(arabic / 1000);
    roman = concatNumLetters("M", thousands);
    arabic -= thousands * 1000;
    }
    if (arabic >= 900) {
    roman += "CM";
    arabic -= 900;
    }
    if (arabic >= 500) {
    roman += "D";
    arabic -= 500;
    }
    if (arabic >= 400) {
    roman += "CD";
    arabic -= 400;
    }
    if (arabic >= 100) { 
    var hundreds = ~~(arabic / 100);
    roman += concatNumLetters("C", hundreds);
    arabic -= hundreds * 100;
    }
    if (arabic >= 90) {
    roman += "XC";
    arabic -= 90;
    }
    if (arabic >= 50) {
    roman += "L";
    arabic -= 50;
    }
    if (arabic >= 40) {
    roman += "XL";
    arabic -= 40;
    }
    if (arabic >= 10) {
    var dozens = ~~(arabic / 10);
    roman += concatNumLetters("X", dozens);
    arabic -= dozens * 10;
    }
    if (arabic >= 9) {
    roman += "IX";
    arabic -= 9;
    }
    if (arabic >= 5) {
    roman += "V";
    arabic -= 5;
    }
    if (arabic >= 4) {
    roman += "IV";
    arabic -= 4;
    }
    if (arabic >= 1) {
    roman += concatNumLetters("I", arabic);
    }
    return roman;
    }
  11. 3
    function convertToRoman(num) {
    var roman = {
    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 result = '';
    for (var key in roman) {
    if (num == roman[key]) {
    return result +=key;
    }
    var check = num > roman[key];
    if(check) {
    result = result + key.repeat(parseInt(num/roman[key]));
    num = num%roman[key];
    }
    }
    return result;
    }
    console.log(convertToRoman(36));
    • Por favor, explique su solución
    • permite tomar 1012 por lo que no es igual a cualquier tecla y también mayor que 1000, que es mi primera clave, por lo que entrará en el 2º si la condición después de que se va a encontrar el cociente será de 1 por lo que tomará resultado y agregar M*1 para él así que ahora el resultado de la variable M en ella y la número 12. Así que ahora 12>10 más que entrar y hacer lo mismo, así que ahora el resultado será MX y num = 2 y de nuevo 2>1 por lo que se agregue MXI y ahora el num = 1. Así que ahora va a entrar en la primera si la condición andmake resultado = MXII.
  12. 2

    He creado dos matrices con números arábigos el otro con los caracteres romanos.

    JS:

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

    Luego he añadido un ciclo que analice los elementos romanos, la adición de la más grande todavía comprendidos en el NUM RESULTADO, entonces nos disminuir el NUM de la misma cantidad.

    Es como el mapa de una parte de NUM en números romanos y, a continuación, nos disminución de la misma cantidad.

    JS:

      for (var x = 0; x < rom.length; x++) {
    while (num >= ara[x]) {
    result += rom[x];
    num -= ara[x];
    }
    }
    return result;
    }

  13. 2

    Si quieres convertir un gran número con más símbolos, tal vez este algo podría ayudar.

    La única premisa de los símbolos es que debe ser impar y siga la misma regla (1, 5, 10, 50,100 …., 10^(N)/2, 10^(N)).

    JS:

    var rnumbers = ["I","V","X","L","C","D","M"];
    rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:1px solid black; padding:1px;">'+n+'</span> '}));
    rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border:1px solid black; border-bottom:1px none black; padding:1px;">'+n+'</span> '}));
    rnumbers = rnumbers.concat(["V","X","L","C","D","M"].map(function(n) {return '<span style="border-top:3px double black; padding:1px;">'+n+'</span> '}));
    String.prototype.repeat = function( num ) {
    return new Array( num + 1 ).join( this );
    };
    function toRoman(n) {
    if(!n) return "";
    var strn = new String(n);
    var strnlength = strn.length;
    var ret = "";
    for(var i = 0 ; i < strnlength; i++) {
    var index = strnlength*2 -2 - i*2;
    var str;
    var m = +strn[i];
    if(index > rnumbers.length -1) {
    str = rnumbers[rnumbers.length-1].repeat(m*Math.pow(10,Math.ceil((index-rnumbers.length)/2)));
    }else {
    str = rnumbers[index].repeat(m);
    if (rnumbers.length >= index + 2) {
    var rnregexp = rnumbers[index]
    .split("(").join('\\(')
    .split(")").join('\\)');
    str = str.replace(new RegExp('(' + rnregexp + '){9}'), rnumbers[index] + rnumbers[index + 2])
    .replace(new RegExp('(' + rnregexp + '){5}'), rnumbers[index + 1])
    .replace(new RegExp('(' + rnregexp + '){4}'), rnumbers[index] + rnumbers[index + 1])
    }
    }
    ret +=str;
    }
    return ret;
    }

    HTML:

        
    <input type="text" value="" onkeyup="document.getElementById('result').innerHTML = toRoman(this.value)"/>
    <br/><br/>
    <div id="result"></div>

  14. 2

    SI este número en HTMLElement (como el español), recomendamos Agregar atributo HTML data-format :

    <p>Phase <span data-format="roman">4 </span> Sales</p>

    Nota : Este no es un estándar de html. El código Javascript utilizado es visible una vez que se desplaza hacia abajo en la sección html en jsfiddle.

    DEMO

  15. 2

    JS:

    function convertToRoman(num) {
    var romans = {
    1000: 'M',
    900: 'CM',
    500: 'D',
    400: 'CD',
    100: 'C',
    90: 'XC',
    50: 'L',
    40: 'XL',
    10: 'X',
    9: 'IX',
    5: 'V',
    4: 'IV',
    1: 'I'
    };
    var popped, rem, roman = '',
    keys = Object.keys(romans);
    while (num > 0) {
    popped = keys.pop();
    m = Math.floor(num / popped);
    num = num % popped;
    console.log('popped:', popped, ' m:', m, ' num:', num, ' roman:', roman);
    while (m-- > 0) {
    roman += romans[popped];
    }
    while (num / popped === 0) {
    popped = keys.pop();
    delete romans[popped];
    }
    }
    return roman;
    }
    var result = convertToRoman(3999);
    console.log(result);
    document.getElementById('roman').innerHTML = 'Roman: ' + result;

    CSS:

    p {
    color: darkblue;
    }

    HTML:

    <p>Decimal: 3999</p>
    <p id="roman">Roman:</p>

  16. 2

    Acabo de hacer esto en freecodecamp. Se puede ampliar fácilmente.

    function convertToRoman(num) {
    var roman ="";
    var values = [1000,900,500,400,100,90,50,40,10,9,5,4,1];
    var literals = ["M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"];
    for(i=0;i<values.length;i++){
    if(num>=values[i]){
    if(5<=num && num<=8) num -= 5;
    else if(1<=num && num<=3) num -= 1;
    else num -= values[i];
    roman += literals[i];
    i--;
    }
    }
    return roman;
    }
  17. 2

    He aquí una expresión regular solución:

    function deromanize(roman) {
    var r = 0;
    //regular expressions to check if valid Roman Number.
    if (!/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/.test(roman))
    throw new Error('Invalid Roman Numeral.');
    roman.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
    r += {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}[i]; 
    });
    return r;
    }
  18. 1
    /*my beginner-nooby solution for numbers 1-999 :)*/
    function convert(num) {
    var RomNumDig = [['','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']];
    var lastDig = num%10;
    var ourNumb1 = RomNumDig[0][lastDig]||'';
    if(num>=10) {
    var decNum = (num - lastDig)/10;
    if(decNum>9)decNum%=10; 
    var ourNumb2 = RomNumDig[1][decNum-1]||'';} 
    if(num>=100) {
    var hundNum = ((num-num%100)/100);
    var ourNumb3 = RomNumDig[2][hundNum-1]||'';}
    return ourNumb3+ourNumb2+ourNumb1;
    }
    console.log(convert(950));//CML
    /*2nd my beginner-nooby solution for numbers 1-10, but it can be easy transformed for larger numbers :)*/
    function convert(num) {
    var ourNumb = '';
    var romNumDig = ['I','IV','V','IX','X'];
    var decNum = [1,4,5,9,10];
    for (var i=decNum.length-1; i>0; i--) {
    while(num>=decNum[i]) {
    ourNumb += romNumDig[i];
    num -= decNum[i];
    }
    }
    return ourNumb;
    }
    console.log(convert(9));//IX
  19. 1
    function toRoman(n) {
    var decimals = [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 < decimals.length; i++) {
    if(n < 1)
    return "";       
    if(n >= decimals[i]) {
    return roman[i] + toRoman(n - decimals[i]);        
    }
    }
    }
  20. 1

    Esta función trabaja en los conjuntos de caracteres diferentes en cada uno de los dígitos. Para agregar otro dígito agregar el número romano de la cadena el 1 lugar, 5 lugar y el próximo 1 de lugar. Esto es bueno porque usted actualización con sólo saber el siguiente conjunto de caracteres utilizados.

    JS:

    function toRoman(n){
    var d=0,o="",v,k="IVXLCDM".split("");
    while(n!=0){
    v=n%10,x=k[d],y=k[d+1],z=k[d+2];
    o=["",x,x+x,x+x+x,x+y,y,y+x,y+x+x,y+x+x+x,x+z][v]+o;
    n=(n-v)/10,d+=2;
    }
    return o
    }
    var out = "";
    for (var i = 0; i < 100; i++) {
    out += toRoman(i) + "\n";
    }
    document.getElementById("output").innerHTML = out;

    HTML:

    <pre id="output"></pre>

  21. 1

    Esto funciona para todos los números sólo en la necesidad de los números romanos M y por debajo.

    function convert(num) {
    var code = [
    [1000, "M"], [900, "CM"], [800, "DCCC"], [700, "DCC"], [600, "DC"],
    [500, "D"], [400, "CD"], [300, "CCC"], [200, "CC"], 
    [100, "C"], [90, "XC"], [80, "LXXX"], [70, "LXX"], [60, "LX"], 
    [50, "L"], [40, "XL"], [30, "XXX"], [20, "XX"], 
    [10, "X"], [9, "IX"], [8, "VIII"], [7, "VII"], [6, "VI"], 
    [5, "V"], [4, "IV"], [3, "III"], [2, "II"], [1, "I"],
    ];
    var rom = "";
    for(var i=0; i<code.length; i++) {
    while(num >= code[i][0]) {
    rom += code[i][1];
    num -= code[i][0];
    }
    }
    return rom;
    }
  22. 1

    Esta es la primera vez que realmente me tiene atascado en freecodecamp. He examinado a través de algunas de las soluciones aquí y quedé sorprendido por lo diferente que estábamos todos. Aquí es lo que terminó trabajando para mí.

    function convertToRoman(num) {
    var roman = "";
    var lookupObj = {
    1000:"M",
    900:"CM",
    500:"D",
    400:"CD",
    100:"C",
    90:"XC",
    50:"L",
    40:"XL",
    10:"X",
    9:"IX",   
    4:"IV",
    5:"V",
    1:"I",
    };
    var arrayLen = Object.keys(lookupObj).length;
    while(num>0){
    for (i=arrayLen-1 ; i>=0 ; i--){
    if(num >= Object.keys(lookupObj)[i]){
    roman = roman + lookupObj[Object.keys(lookupObj)[i]];        
    num = num - Object.keys(lookupObj)[i];
    break;
    }
    }
    }    
    return roman;
    }
    convertToRoman(1231);
  23. 1
    function convertToRoman(num) {
    var romNumerals = [["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 runningTotal = 0;
    var roman = "";
    for (var i = 0; i < romNumerals.length; i++) {
    while (runningTotal + romNumerals[i][1] <= num) {
    runningTotal += romNumerals[i][1];
    roman += romNumerals[i][0];
    }
    }
    return roman;
    }
  24. 1
    function convertToRoman(num) {
    var roNumerals = {
    M: Math.floor(num / 1000),
    CM: Math.floor(num % 1000 / 900),
    D: Math.floor(num % 1000 % 900 / 500),
    CD: Math.floor(num % 1000 % 900 % 500 / 400),
    C: Math.floor(num % 1000 % 900 % 500 % 400 / 100),
    XC: Math.floor(num % 1000 % 900 % 500 % 400 % 100 / 90),
    L: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 / 50),
    XL: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 / 40),
    X: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 / 10),
    IX: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 / 9),
    V: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 / 5),
    IV: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 % 5 / 4),
    I: Math.floor(num % 1000 % 900 % 500 % 400 % 100 % 90 % 50 % 40 % 10 % 9 % 5 % 4 / 1)
    };
    var roNuStr = "";
    for (var prop in roNumerals) {
    for (i = 0; i < roNumerals[prop]; i++) {
    roNuStr += prop;
    }
    }
    return roNuStr;
    }
    convertToRoman(9);
  25. 1
    function convertToRoman (num) {
    var v = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
    var r = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
    var s = "";
    for(i = 0; i < v.length; i++) {
    value = parseInt(num/v[i]);
    for(j = 0; j < value; j++) {
    s += r[i];
    }
    num = num%v[i];
    }
    return s;
    }
  26. 1

    Todavía orgulloso de eso 🙂 funciona entre 1-3999.

    var converterArray = [{"1":["I","IV","V","IX"],
    "2":["X","XL","L","XC"],
    "3":["C","CD","D","CM"],
    "4":["M"]}
    ];
    function convertToRoman(num) {
    var romanNumeral = [];
    var numArr = num.toString().split('');
    var numLength = numArr.length;
    for (var i = 0; i<numArr.length; i++) {
    if (numArr[i] < 4) {
    for (var j = 0; j<numArr[i]; j++) {
    romanNumeral.push(converterArray[0][numLength][0]);
    }
    } else if (numArr[i] < 5) {
    for (var j = 3; j<numArr[i]; j++) {
    romanNumeral.push(converterArray[0][numLength][1]);
    }
    } else if (numArr[i] < 9) {
    romanNumeral.push(converterArray[0][numLength][2]);
    for (var j = 5; j<numArr[i]; j++) {
    romanNumeral.push(converterArray[0][numLength][0]);
    }
    } else if (numArr[i] < 10) {
    for (var j = 8; j<numArr[i]; j++) {
    romanNumeral.push(converterArray[0][numLength][3]);
    }
    }
    numLength--;
    }
    return romanNumeral.join('');
    }
    convertToRoman(9);
    • Esta es la forma en grande y demasiado complicado
    • Gracias por los comentarios, tienes toda la razón! Lo hice hace una semana, ahora me refactord un poco.
  27. 1

    Mi solución rompe el número en una matriz de cadenas, agrega ceros a cada elemento según su posición respecto a la longitud de la matriz, convierte las nuevas cadenas de ceros a los números romanos, y luego se une de nuevo juntos. Esto sólo funcionará con los números hasta el 3999:

    function convertToRoman(num){
    var rnumerals = { 1 : 'I', 2 : 'II', 3 : 'III', 4 : 'IV', 5 : 'V', 6   : 'VI', 7 : 'VII', 
    8 : 'VIII', 9 : 'IX', 10 : 'X', 20 : 'XX', 30 : 'XXX', 40 : 'XL', 50 : 'L', 
    60 : 'LX', 70 : 'LXX', 80 : 'LXXX', 90 : 'XC', 100 : 'C', 200 : 'CC', 300 : 'CCC', 
    400 : 'CD', 500 : 'D', 600 : 'DC', 700 : 'DCC', 800 : 'DCCC', 900 : 'CM', 
    1000: 'M', 2000: 'MM', 3000: 'MMM'};
    var zeros, romNum;
    var arr = num.toString().split("");
    var romArr = [];
    for(var i=0; i < arr.length; i++){
    zeros = "0".repeat((arr.length - i - 1));
    arr[i] = arr[i].concat(zeros);
    romArr.push(rnumerals[(arr[i])]); 
    }
    romNum = romArr.join('');
    return romNum;
    }
  28. 1

    Si es sólo para visualización propósito, usar el HTML estándar con un poco de JS para el valor (si es necesario) y CSS para hacer en línea:

    CSS:

    ol.roman-lowercase,
    ol.roman-uppercase {
    display: inline-flex;
    margin: 0;
    padding: 0;
    }
    ol.roman-lowercase {
    list-style: lower-roman inside;
    }
    ol.roman-uppercase {
    list-style: upper-roman inside;
    }

    HTML:

    <ol class="roman-lowercase"><li value="4"></li></ol> <!-- iv. -->
    <ol class="roman-uppercase"><li value="142"></li></ol> <!-- CXLII. -->

  29. 1

    JS:

    function convertToRoman(num) {
    var arr = [];
    for (var i = 0; i < num.toString().length; i++) {
    arr.push(Number(num.toString().substr(i, 1)));
    }
    var romanArr = [
    ["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"]
    ];
    var roman = arr.reverse().map(function (val, i) {
    if (val === 0) {
    return "";
    }
    if (i === 3) {
    var r = "";
    for (var j = 0; j < val; j++) {
    r += romanArr[i][0];
    }
    return r;
    } else {
    return romanArr[i][val - 1];
    }
    });
    console.log(roman.reverse().join(""));
    return roman.join("");
    }
    convertToRoman(10);

    • En general, las respuestas son mucho más útiles si se incluye una explicación de lo que el código está destinado a hacer, y por eso que resuelve el problema sin la introducción de otros.
  30. 1

    Siento que mi solución es mucho más legible y fácil de entender.

    var intToRoman = function(num) {
    let symbolMap = ['I','V','X','L','C','D','M','P','Q'];
    if (num < 1 || num > 9999) {
    return null;
    }
    let i = 0;
    let result = '';
    while (num) {
    let digit = num % 10;
    num = parseInt(num / 10);
    switch (digit) {
    case 1: result = symbolMap[i] + result;
    break;
    case 2: result = symbolMap[i] + symbolMap[i] + result;
    break;
    case 3: result = symbolMap[i] + symbolMap[i] + symbolMap[i] + result;
    break;
    case 4: result = symbolMap[i] + symbolMap[i+1] + result;
    break;
    case 5: result = symbolMap[i+1] + result;
    break;
    case 6: result = symbolMap[i+1] + symbolMap[i] + result;
    break;
    case 7: result = symbolMap[i+1] + symbolMap[i] + symbolMap[i] + result;
    break;
    case 8: result = symbolMap[i+1] + symbolMap[i] + symbolMap[i] + symbolMap[i] + result;
    break;
    case 9: result = symbolMap[i] + symbolMap[i+2] + result;
    break;
    }
    i += 2;
    }
    return result;
    };
  31. 1

    Sé que esta es una fecha de la pregunta, pero tengo la menor solución de los mencionados aquí y pensé que iba a compartir ya que creo que es más fácil de entender.

    Esta versión no requiere ningún tipo de codificado lógica para los casos extremos, tales como 4(IV),9(IX),40(XL),900(CM), etc. como los otros. Esto también significa que puede manejar grandes números mayores que la máxima romana escala podría (3999). Por ejemplo, si «T» se convirtió en un nuevo símbolo que se podría agregar al principio de la romanLookup objeto y sería mantener el mismo algorítmica afectan; o supuesto, asumiendo el «no más de 3 símbolos iguales en una fila» se aplica la regla.

    He probado este en contra de un conjunto de datos de 1-3999 y funciona a la perfección.

    function convertToRoman(num) {
    //create key:value pairs
    var romanLookup = {M:1000, D:500, C:100, L:50, X:10, V:5, I:1};
    var roman = [];
    var romanKeys = Object.keys(romanLookup);
    var curValue;
    var index;
    var count = 1;
    for(var numeral in romanLookup){
    curValue = romanLookup[numeral];
    index = romanKeys.indexOf(numeral);
    while(num >= curValue){
    if(count < 4){
    //push up to 3 of the same numeral
    roman.push(numeral);
    } else {
    //else we had to push four, so we need to convert the numerals 
    //to the next highest denomination "coloring-up in poker speak"
    //Note: We need to check previous index because it might be part of the current number.
    //Example:(9) would attempt (VIIII) so we would need to remove the V as well as the I's
    //otherwise removing just the last three III would be incorrect, because the swap 
    //would give us (VIX) instead of the correct answer (IX)
    if(roman.indexOf(romanKeys[index - 1]) > -1){
    //remove the previous numeral we worked with 
    //and everything after it since we will replace them
    roman.splice(roman.indexOf(romanKeys[index - 1]));
    //push the current numeral and the one that appeared two iterations ago; 
    //think (IX) where we skip (V)
    roman.push(romanKeys[index], romanKeys[index - 2]);
    } else {
    //else Example:(4) would attemt (IIII) so remove three I's and replace with a V 
    //to get the correct answer of (IV)
    //remove the last 3 numerals which are all the same
    roman.splice(-3);
    //push the current numeral and the one that appeared right before it; think (IV)
    roman.push(romanKeys[index], romanKeys[index - 1]);
    }
    }
    //reduce our number by the value we already converted to a numeral
    num -= curValue;
    count++;
    }
    count = 1;
    }
    return roman.join("");
    }
    convertToRoman(36);
    • ¿Por qué esto obtener un downvote? Es un trabajo como es el ejemplo de que responde a la pregunta y está muy bien documentado?
  32. 0
    var romanNumerals = [
    ['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]];
    RomanNumerals = {
    romerate: function(foo) {
    var bar = '';
    romanNumerals.forEach(function(buzz) {
    while (foo >= buzz[1]) {
    bar += buzz[0];
    foo -= buzz[1]; 
    }
    });
    return bar;
    },
    numerate: function(x) {
    var y = 0;
    romanNumerals.forEach(function(z) {
    while (x.substr(0, z[0].length) == z[0]) {
    x = x.substr(z[0].length);
    y += z[1];
    }
    });
    return y;
    }
    };
  33. 0

    Bien, parece que no soy el único que se quedó atascado en este reto en FreeCodeCamp. Pero me gustaría compartir mi código con usted de todos modos. Es muy potente, casi un 10% más rápido que la parte superior-votaron a favor de la solución aquí (yo no he probado todos los demás, y supongo que lo mío no es el más rápido). Pero creo que es limpio y fácil de entender:

    function convertToRoman(num) {
    //Some error checking first
    if (+num > 9999) {
    console.error('Error (fn convertToRoman(num)): Can\'t convert numbers greater than 9999. You provided: ' + num);
    return false;
    }
    if (!+num) {
    console.error('Error (fn convertToRoman(num)): \'num\' must be a number or number in a string. You provided: ' + num);
    return false;
    }
    //Convert the number into
    //an array of the numbers
    var arr = String(+num).split('').map((el) => +el );
    //Keys to the roman numbers
    var keys = {
    1: ['', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX'],
    2: ['', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC'],
    3: ['', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM'],
    4: ['', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM', 'MMMMMM', 'MMMMMMM', 'MMMMMMMM', 'MMMMMMMMM'],
    };
    //Variables to help building the roman string
    var i = arr.length;
    var roman = '';
    //Iterate over each number in the array and
    //build the string with the corresponding
    //roman numeral
    arr.forEach(function (el) {
    roman += keys[i][el];
    i--;
    });
    //Return the string
    return roman;
    }

    Puede parecer una limitación, que sólo puede convertir los números hasta el 9 999. Pero el hecho es que a partir de 10 000 y por encima de una línea debe estar siempre por encima de los literales. Y que no se han resuelto todavía.

    Espero que esto le ayudará.

  34. 0
    function convertToRoman(num) {
    var search = {
    "0":["I","II","III","IV","V","VI","VII","VIII","IX"],
    "1":["X","XX","XXX","XL","L","LX","LXX","LXXX","XC"],
    "2":["C","CC","CCC","CD","D","DC","DCC","DCCC","CM"],
    "3":["M","MM","MMM","MV^","V^","V^M","V^MM","V^MMM","MX^"],
    };
    var numArr = num.toString().split("").reverse();
    var romanReturn = [];
    for(var i=0; i<numArr.length; i++){
    romanReturn.unshift(search[i][numArr[i]-1]);
    }
    return romanReturn.join("");
    }
  35. 0

    Esta es mi solución, no estoy muy seguro de cómo se realiza.

    function convertToRoman(num) {
    var uni = ["","I","II","III","IV","V","VI","VII","VIII","IX"];
    var dec = ["","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"];
    var cen = ["","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"];
    var mil = ["","M","MM","MMM","MMMM","MMMMM","MMMMMM","MMMMMMM","MMMMMMMM","MMMMMMMMMM"];
    var res =[];
    if(num/1000 > 0)
    {
    res = res.concat(mil[Math.floor(num/1000)]);
    }
    if(num/100 > 0)
    {
    res = res.concat(cen[Math.floor((num%1000)/100)]);
    }
    if(num/10 >0)
    {
    res = res.concat(dec[Math.floor(((num%1000)%100)/10)]);
    }
    res=res.concat(uni[Math.floor(((num%1000)%100)%10)]);
    return res.join('');
    }
  36. 0

    Yo sólo soy la publicación de una función que he hecho para convertir a la Romana, espero que os guste

    function converter(numToConv) {
    var numToRom = [];
    var numToRome = "";
    var R = [['M',1000], ['D',500], ['C',100], ['L',50], ['X',10], ['V',5], ['I',1]];
    while (numToConv > 0) {
    if (numToConv > R[0][1]) {
    if (numToConv < R[0][1] * 5 - R[0][1]) {   
    numToRom.push([R[0][0],"next one goes aftah"]);
    numToConv = Math.abs(numToConv - R[0][1]);
    console.log("Next comes after: " + R[0][0] + " (" + R[0][1] + ")");
    console.log(numToConv);
    } else {
    numToConv = 0;
    break;
    }
    }
    for (var i = 0; i < R.length; i++) {
    if (R[i][1] == numToConv) {
    numToRom.push([R[i][0],"end"]);
    numToConv = Math.abs(numToConv - R[i][1]);
    console.log("End: " + numToConv);
    } else if (i > 0) {
    if ((R[i-1][1] > numToConv) && (R[i][1] < numToConv)) {
    console.log(numToConv + " is between: " + R[i][1]  + " (" + R[i][0] + ") and: " +  R[i - 1][1]  + " (" + R[i - 1][0] + ")");
    var threshold = R[i - 1][1] - Math.pow(10, numToConv.toString().length - 1);
    console.log("threshold: " + threshold + " : " + R[i][1] + " : " + Math.pow(10, numToConv.toString().length - 1));
    if (numToConv  < threshold) {
    numToRom.push([R[i][0],"next one goes aftah"]);
    numToConv = Math.abs(numToConv - R[i][1]);
    console.log("Next comes after: " + R[i][0] + " (" + R[i][1] + ")");
    console.log(numToConv);
    } else {
    numToRom.push([R[i-1][0],"next one goes befoah"]);
    numToConv = Math.abs(numToConv - threshold + Math.pow(10, numToConv.toString().length - 1));
    console.log("Next comes before: " + R[i-1][0] + " (" + R[i-1][1] + ")");
    console.log(numToConv);
    }
    }
    }
    }
    }
    console.log("numToRom: " + numToRom);
    for (var i = 0; i < numToRom.length; i++) {
    if (numToRom[i][1] == "next one goes befoah") {
    numToRome += (numToRom[i+1][0] + numToRom[i][0]);
    console.log("numToRome goes befoah: " + numToRome + " i: " + i);
    i++;
    } else {
    numToRome += numToRom[i][0];
    console.log("numToRome goes aftah: " + numToRome + " i: " + i);
    }
    }
    console.log("numToRome: " + numToRome);
    return numToRome;

    }

    El código editado con los comentarios:

    function converter(numToConv) {
    var numToRom = []; //an array empty, ready to store information about the numbers we will use as we analyse the given number 
    var numToRome = ""; //this is a string to add the Roman letters forming our returning number
    var R = [['M',1000], ['D',500], ['C',100], ['L',50], ['X',10], ['V',5], ['I',1]]; //this array stores the matches with the arabic numbers that we are going to need
    while (numToConv > 0) { //just checking, there is no zero
    if (numToConv > R[0][1]) { //checks if the number is bigger than the bigger number in the array
    if (numToConv < R[0][1] * 5 - R[0][1]) { //checks if it is larger even than 4 times the larger number in the array (just because there is not usually a way to express a number by putting 4 times the same letter i.e there is no "IIII", or "XXXX" etc)
    numToRom.push([R[0][0],"next one goes aftah"]);//here is the information we want to pass, we add the letter we are about to use along with info about the next letter
    numToConv = Math.abs(numToConv - R[0][1]);//and now we are subtracting the value of the letter we are using from the number
    console.log("Next comes after: " + R[0][0] + " (" + R[0][1] + ")");//informing about what we encountering
    console.log(numToConv);//..as well as what's the next number
    } else { //if the number is larger than 4 times the larger number in the array (thus it cannot be expressed)
    numToConv = 0; //then 0 the number (unnecessary but still, no problem doing it)
    break;//and of course, breaking the loop, no need to continue
    }
    }
    for (var i = 0; i < R.length; i++) {//now we are about to search our number for each cell of the array with the roman letters (again and again)
    if (R[i][1] == numToConv) { //if the number is equal to the one in the cell (that means the conversion is over)
    numToRom.push([R[i][0],"end"]); //we pass the information about that cell along with the indication that the conversion has ended
    numToConv = Math.abs(numToConv - R[i][1]);//thai can also be skipped but again there is o harm in keeping it
    console.log("End: " + numToConv);//again informing about what we encountering
    } else if (i > 0) { //just a precaution because we are about to use "i-1" 
    if ((R[i-1][1] > numToConv) && (R[i][1] < numToConv)) {//we find the range in which is the given number (for instance: the number 4 is between 1[I] and 5[V])
    console.log(numToConv + " is between: " + R[i][1]  + " (" + R[i][0] + ") and: " +  R[i - 1][1]  + " (" + R[i - 1][0] + ")");//once again informing
    var threshold = R[i - 1][1] - Math.pow(10, numToConv.toString().length - 1);//we create this "threshold" to check if the next number is going before or after this one (difference between 7[VII] and 9[IX]). it is the larger number of our range - 10^[depends on how large is the number we want to convert] (for 999, the threshold is 900, it is smaller 1000 - 10^2)
    console.log("threshold: " + threshold + " : " + numToConv + " : " + R[i - 1][1] + " : " + R[i][1] + " : " + Math.pow(10, numToConv.toString().length - 1));
    if (numToConv  < threshold) {//if the number is smaller than the "threshold" (like 199 where its threshold is 400)
    numToRom.push([R[i][0],"next one goes aftah"]);//then the next number is going after
    numToConv = Math.abs(numToConv - R[i][1]);//and again, subtract the used value of the number we are converting
    console.log("Next comes after: " + R[i][0] + " (" + R[i][1] + ")");
    console.log(numToConv);
    } else { //now, if the number is larger than the threshold (like 99 where its threshold is 90)
    numToRom.push([R[i-1][0],"next one goes befoah"]);//then the next number is going before the one we add now
    numToConv = Math.abs(numToConv - R[i - 1][1]);//again, the subtraction, it was "threshold + Math.pow(10, numToConv.toString().length - 1)" but I changed it to "R[i - 1][1]", same result, less operations
    console.log("Next comes before: " + R[i-1][0] + " (" + R[i-1][1] + ")");
    console.log(numToConv);
    }
    }
    }
    }
    }
    console.log("numToRom: " + numToRom); //now that we have all the info we need about the number, show it to the log (just for a check)
    for (var i = 0; i < numToRom.length; i++) {//..and we start running through that info to create our final number
    if (numToRom[i][1] == "next one goes befoah") {//if our information about the cell tells us that the next letter is going before the current one
    numToRome += (numToRom[i+1][0] + numToRom[i][0]);//we add both to our string (the next one first)
    console.log("numToRome goes befoah: " + numToRome + " i: " + i);
    i++;//and we add an extra '1' to the i, so it will skip the next letter (mind that there won't be more than one letters saying that the next one is going before them in a row
    } else {//if the next one is going after the current one
    numToRome += numToRom[i][0]; //we just add the one we are on to the string and go forth
    console.log("numToRome goes aftah: " + numToRome + " i: " + i);
    }
    }
    console.log("numToRome: " + numToRome);
    return numToRome;//return the string and we are done
    }
    • una explicación del código aumentaría el valor de respuesta
    • ¿Acaba de publicar una copia de la biblioteca jQuery 😉 me tomó un tiempo para leer esto, puede que quiero simplificar.
    • Lo siento chicos, acabo de ver tus comentarios. Me ‘ll agregar comentarios al código ASAP
    • Lo hizo, he añadido algunos comentarios (aunque me temo que yo lo hice demasiado)
  37. 0
    function toRoman(n) {
    var r = '';
    for (var c = 0; c < n.length; c++)
    r += calcDigit(eval(n.charAt(c)), n.length - c - 1);
    return r
    }
    function Level(i, v, x) {
    this.i = i;
    this.v = v;
    this.x = x
    }
    levels = [];
    levels[0] = new Level('I','V','X');
    levels[1] = new Level('X','L','C');
    levels[2] = new Level('C','D','M');
    function calcDigit(d, l) {
    if (l > 2) {
    var str = '';
    for (var m = 1; m <= d * Math.pow(10, l - 3); m++)
    str += 'M';
    return str
    } else if (d == 1)
    return levels[l].i;
    else if (d == 2)
    return levels[l].i + levels[l].i;
    else if (d == 3)
    return levels[l].i + levels[l].i + levels[l].i;
    else if (d == 4)
    return levels[l].i + levels[l].v;
    else if (d == 5)
    return levels[l].v;
    else if (d == 6)
    return levels[l].v + levels[l].i;
    else if (d == 7)
    return levels[l].v + levels[l].i + levels[l].i;
    else if (d == 8)
    return levels[l].v + levels[l].i + levels[l].i + levels[l].i;
    else if (d == 9)
    return levels[l].i + levels[l].x;
    else
    return ''
    }
  38. 0

    Odio listado de todas las posibilidades en una matriz ( que muchas personas eligen para resolver este rompecabezas), por lo que el uso de otra función para hacer ese trabajo. Aquí está mi solución:

    JS:

    //a function that convert a single number to roman number, you can choose how to convert it so later you can apply to different part of the number
    function romannum(num,rnum1,rnum2,rnum3){
    var result = "";
    if(num >= 1 && num < 4){
    while(num>0){
    result += rnum1;
    num--;
    }
    }
    else if(num > 5 && num < 9){
    result = rnum2;
    while(num>5){
    result += rnum1;
    num--;
    }  
    }
    else if(num == 4){
    result += rnum1 + rnum2;
    }
    else if( num == 5){
    result += rnum2;
    }
    else if( num == 9){
    result += rnum1+ rnum3;
    }
    return result;
    }
    //the main function
    function convertToRoman(num) {
    num = num.toString().split('');
    var length = num.length;
    var x = 0;
    var result =[];
    while((length - x) > 0){
    if(length -x === 4){
    result.push(romannum(num[x],"M","",""));
    }
    else if(length -x  === 3){
    result.push(romannum(num[x],"C","D","M"));
    }
    else if(length - x  === 2){
    result.push(romannum(num[x],"X","L","C"));
    }
    else if(length - x === 1){
    result.push(romannum(num[x],"I","V","X"));
    }
    x++;  
    }

  39. 0

    En este código, el límite superior de los números se pueden ampliar mediante la adición de nuevas cartas a letterTable:

    letterTable = {
    0:{
    1:'I',
    5:'V',
    10:'X'
    },
    1:{
    1:'X',
    5:'L',
    10:'C'
    },
    2:{
    1:'C',
    5:'D',
    10:'M'
    },
    3:{
    1:'M',
    5:'V', //There should be a dash over this letter
    10:'X' //There should be a dash over this letter
    }, 
    //you can add new level of letters here
    };
    function romanLetter(i, j){
    romanTable = {
    '0':'',
    '1':letterTable[i][1],
    '2':letterTable[i][1]+letterTable[i][1],
    '3':letterTable[i][1]+letterTable[i][1]+letterTable[i][1],
    '4':letterTable[i][1]+letterTable[i][5],
    '5':letterTable[i][5],
    '6':letterTable[i][5]+letterTable[i][1],
    '7':letterTable[i][5]+letterTable[i][1]+letterTable[i][1],
    '8':letterTable[i][5]+letterTable[i][1]+letterTable[i][1]+letterTable[i][1],
    '9':letterTable[i][1]+letterTable[i][10]
    };
    return romanTable[j];
    }
    function convertToRoman(num) {
    numStr = String(num);
    var result = '';
    var level = 0;
    for (var i=numStr.length-1; i>-1; i--){
    result = romanLetter(level, numStr[i]) + result;
    level++;
    }
    return result;
    }
  40. 0

    Aquí está mi «como funcional como se pone» solución.

    JS:

    var numerals = ["I","V","X","L","C","D","M"],
    number = 1453,
    digits = Array(~~(Math.log10(number)+1)).fill(number).map((n,i) => Math.trunc(n%Math.pow(10,i+1)/Math.pow(10,i))),  //<- [3,5,4,1]
    result = digits.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(result);

  41. 0

    Mientras que mi respuesta no es tan eficiente como otros, mi enfoque era más difícil de codificación en la base de los números y permitir que el programa para averiguar el resto.

    Por ejemplo…

    En lugar de:

    number = [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']

    He utilizado:

    base = ['I', 'X', 'C', 'M'];
    pivot = ['V', 'L', 'D'];

    function basicRomanNumerals(num){
    let base = ['I', 'X', 'C', 'M'];
    let pivot = ['V', 'L', 'D'];
    return String(num).split('').reverse().map(function(num, idx){
    let distance = +num - 5;
    let is1AwayFromNext = Math.abs(+num - 10) === 1;
    if(Math.abs(distance)=== 1 || is1AwayFromNext){
    if(is1AwayFromNext){
    return base[idx]+""+base[idx+1];
    }else if ( distance < 0 ){
    return base[idx]+""+pivot[idx];
    }else{
    return pivot[idx]+""+base[idx];
    }
    }else if(distance === 0){
    return pivot[idx];
    }else if(distance > 1){
    return pivot[idx]+""+base[idx].repeat(+num-5);
    }else{
    return base[idx].repeat(+num);
    }
    }).reverse().join('');
  42. 0

    Acabo de terminar este en freeCodeCamp demasiado, no vi esta solución particular. Sé que esta solución puede ser optimizado con la recursividad, pero sólo quería tirar por ahí, así que al menos se pueden ver otras opciones:

    function convertToRoman(num) {
    var value = [];
    var temp, base, buffer;
    var letters = ['I', 'V', 'X', 'L', 'C', 'D', 'M'];
    var offsets = [
    [1, 0],  //1
    [2, 0],  //2
    [3, 0],  //3
    [-1, 1], //4
    [0, 1],  //5
    [1, 1],  //6
    [2, 1],  //7
    [3, 1],  //8
    [-2, 2],  //9
    ];
    //cascade through each denomination (1000's, 100's, 10's, 1's) so that each denomination is triggered
    //Thousands
    if (num >= 1000) {
    temp = Math.floor(num / 1000);
    buffer = offsets[temp - 1];
    base = 6;
    value.push(getValue(base, letters, buffer));
    num -= temp * 1000;
    }
    //Hundreds
    if (num >= 100) {
    temp = Math.floor(num / 100);
    buffer = offsets[temp - 1];
    base = 4;
    value.push(getValue(base, letters, buffer));
    num -= temp * 100;
    }
    //Tens
    if (num >= 10) {
    temp = Math.floor(num / 10);
    buffer = offsets[temp - 1];
    base = 2;
    value.push(getValue(base, letters, buffer));
    num -= temp * 10;
    }
    //Ones
    if (num > 0) {
    buffer = offsets[num - 1];
    base = 0;
    value.push(getValue(base, letters, buffer));
    }
    //Finish
    return value.join('');
    }
    function getValue(base, letters, buffer) {
    var val1 = buffer[0], val2 = buffer[1];
    var value = [];
    //If val1 is less than 0 then we know it is either a 4 or 9, which has special cases
    if (val1 < 0) {
    //Push the base index, then push the base plus the val2 offset
    value.push(letters[base]);
    value.push(letters[base + val2]);
    } else {
    //Push a letter if val2 is set - meaning we need to offset a number that is equal to or higher than 5
    //5 is basically the only scenario which this will exist
    if (val2 > 0) value.push(letters[base + val2]);
    //Now add in the next letters of the base for the inciment
    for (var i = 0; i < val1; i++) {
    value.push(letters[base]);
    }
    }
    return value.join('');
    }
    convertToRoman(90);

    Estoy bastante seguro de que el compañero función puede tener casi ilimitado potencial, suponiendo que proporcionan los símbolos correctos para números más grandes de M, pero no me fijé en eso.

  43. 0

    He aquí una manera de hacerlo sin tener que recorrer todos los diferentes números romanos y sus números correspondientes. Tiene una constante de tiempo O(1) de búsqueda, ahorrar un poco en el tiempo de la complejidad.

    Se descompone cada entero de derecha a izquierda, así que 2,473 se convierte en 3 + 70 + 400 + 2,000, y luego encuentra el correspondiente número romano el uso de la romanNumerals de la tabla hash, y lo anexa a la cadena de resultado. Esto se hace mediante la adición de un adicional de 0 para cada entero antes de la búsqueda como usted se mueve de derecha a izquierda. Esta solución sólo funciona para los números entre 1 y 3,999.

        function integerToRoman(int) {
    if (int < 1 || int > 3999) {
    return -1;
    }
    var result = '';
    var intStr = int.toString();
    var romanNumerals = { 1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V', 6: 'VI', 7: 'VII', 8: 'VIII', 9: 'IX', 10: 'X', 20: 'XX', 30: 'XXX', 40: 'XL', 50: 'L', 60: 'LX', 70: 'LXX', 80: 'LXXX', 90: 'XC', 100: 'C', 200: 'CC', 300: 'CCC', 400: 'CD', 500: 'D', 600: 'DC', 700: 'DCC', 800: 'DCCC', 900: 'CM', 1000: 'M', 2000: 'MM', 3000: 'MMM'};
    var digit = '';
    for (var i = intStr.length - 1; i >= 0; i-- ) {
    if (intStr[i] === '0') {
    digit += '0';
    continue;
    }
    var num = intStr[i] + digit;
    result = romanNumerals[num] + result;
    digit += '0';
    }
    return result;
    }
  44. 0

    JS:

    const romanize = num => {
    const romans = {
    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 roman = '';
    for (let key in romans) {
    const times = Math.trunc(num / romans[key]);
    roman += key.repeat(times);
    num -= romans[key] * times;
    }
    return roman;
    }
    console.log(
    romanize(38)
    )

  45. 0

    Aquí está mi solución:

    function convertToRoman(num) { 
    let romanNum = "";
    const strNum = String(num);
    const romans = {
    1: ["I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"], //ones
    2: ["X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"], //tens
    3: ["C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"], //hundreds
    4: ["M", "MM", "MMM"] //thousands
    };
    for (let i = 1; i <= strNum.length; i++)
    if (Number(strNum[strNum.length - i]) !== 0)
    romanNum = romans[i][strNum[strNum.length - i] - 1] + romanNum;
    return romanNum;
    }

    Se desempeña muy bien en Chrome 60 – https://jsperf.com/num-to-roman

  46. 0
    function convertToRoman(int) {
    console.log('Number:', int);
    let roman = [];
    let i, k, replacement;
    let seq = ['I', 'V', 'X', 'L', 'C', 'D', 'M'];
    while (int > 999) {
    roman.push('M');
    int -= 1000;
    }
    while (int > 499) {
    roman.push('D');
    int -= 500;
    }
    while (int > 99) {
    roman.push('C');
    int -= 100;
    }
    while (int > 49) {
    roman.push('L');
    int -= 50;
    }
    while (int > 9) {
    roman.push('X');
    int -= 10;
    }
    while (int > 4) {
    roman.push('V');
    int -= 5;
    }
    while (int >= 1) {
    roman.push('I');
    int -= 1;
    }
    //Replace recurrences of 4 ('IIII' to 'IV')
    for (i = 0; i < roman.length; i++) {
    if (roman[i] == roman[i + 1] &&
    roman[i] == roman[i + 2] &&
    roman[i] == roman[i + 3]) {
    for (k = 0; k < seq.length; k++) {
    if (roman[i] == seq[k]) {
    replacement = seq[k + 1];
    }
    }
    roman.splice(i + 1, 3, replacement);
    }
    }
    //Converting incorrect recurrences ('VIV' to 'IX')
    for (i = 0; i < roman.length; i++) {
    if (roman[i] == roman[i + 2] && roman[i] != roman[i + 1]) {
    for (k = 0; k < seq.length; k++) {
    if (roman[i] == seq[k]) {
    replacement = seq[k + 1];
    }
    }
    roman[i + 2] = replacement;
    roman.splice(i, 1);
    }
    }
    roman = roman.join('');
    return roman;
    }
  47. 0

    JS:

    function convertToRoman(num) {
    var toTen = ["", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X"];
    var toHungred = ["", "X" ,"XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC", "C"];
    var toThousend = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM", "M"];  			
    var arrString = String(num).split("");  
    var arr = [];           
    if (arrString.length == 3 ){  				
    arr.push(toThousend[arrString[+0]]);
    arr.push(toHungred[arrString[+1]]);
    arr.push(toTen[arrString[+2]]);
    } 
    else if (arrString.length == 2 ){  				
    arr.push(toHungred[arrString[+0]]);
    arr.push(toTen[arrString[+1]]);  			  	
    }
    else if (arrString.length == 1 ){  				
    arr.push(toTen[arrString[+0]]);  			  	  	
    }
    else if (arrString.length == 4 ) {
    for (var i =1; i<=[arrString[+0]]; i++) {
    arr.push("M");                  
    }
    arr.push(toThousend[arrString[+1]]);
    arr.push(toHungred[arrString[+2]]);
    arr.push(toTen[arrString[+3]]);
    }              
    console.log (arr.join(""));
    }
    convertToRoman(36);

    • usted debe agregar comentarios y explicación
  48. 0

    Después de haber visto todas las anteriores 46 soluciones para el «Número-A-Romana», ya que esta pregunta fue hecha, sólo hay un post para el reverso Romano-a-Número de kennebec, y que tiene varios problemas: «Número» objeto no puede ser directamente prolongado, deberá utilizar el prototipo. También la creación de prototipos no tienen sentido en este contexto (objeto String es un mejor candidato si los hubiere). En segundo lugar es innecesariamente complejo y, además, las llamadas toRoman método. En tercer lugar, se produce un error para los números mayores que 4000. Aquí es un elegante y la más concisa de todos los 47 puestos para el tipo de conversiones. Estas conversiones de trabajo, fundamentalmente, para cualquier número. El romanToNumber es una pequeña variación de gregoryr la elegante solución:

    JS:

    function numberToRoman(val,rom){ //returns empty string if invalid number
    rom=rom||''
    if(isNaN(val)||val==0) 
    return rom;
    for(i=0;curval=[1000,900,500,400,100,90,50,40,10,9,5,4,1][i],i<13;i++)
    if(val >= curval)
    return numberToRoman(val-curval,rom+['M','CM','D','CD','C','XC','L','XL','X','IX','V','IV','I'][i])
    }
    function romanToNumber(txtRom){//returns NaN if invalid string
    txtRom=txtRom.toUpperCase();
    if (!/^M*(CM|CD|(D?C{0,3}))?(XC|XL|(L?X{0,3}))?(IX|IV|(V?I{0,3}))?$/.test(txtRom))
    return NaN;
    var retval=0;
    txtRom.replace(/[MDLV]|C[MD]?|X[CL]?|I[XV]?/g, function(i) {
    retval += {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}[i]; 
    });
    return retval;
    }

    CSS:

    #tblRoman{border-collapse:collapse;font-family:sans-serif;font-size:.8em}

    HTML:

    <h3>Roman to Number Conversion</h3>
    <input type="button" value="example 1" onclick="document.getElementById('romanval').value='mmmmmmmcdlxxxiv'">
    <input type="button" value="example 2" onclick="document.getElementById('romanval').value='mmmmmmmdclxxxiv'">
    <input type="button" value="example 3" onclick="document.getElementById('romanval').value='mmmmmmmdxcdlxxxiv'">
    <p>
    Enter a Roman Number below, or click on an example button. Then click Convert 
    </p>
    <input type="text" size="40" id="romanval">
    <input type="button" onclick="document.getElementById('resultval').innerText
    = romanToNumber(document.getElementById('romanval').value)" value="Convert"> 
    <p />
    Numeric Value: <b id="resultval"></b>
    <hr>
    <h3>Number to Roman Conversion</h3>
    <input type="button" value="Generate table upto 2000" onclick="document.getElementById('tblRoman').innerHTML ='</tr>'+[...Array(2000).keys()].map(x => '<td>'+(x+1)+': '+numberToRoman(x+1)+'</td>'+((x+1)%10==0?'</tr><tr>':'')).join('')+'</tr>'">
    <table id="tblRoman" border></table>

  49. 0

    acaba de conectar en la respuesta de Piotr Berebecki.
    He editado para que la función recursiva no sólo restar 1 al número dado, pero inmediatamente se resta la máxima coincidente número en la matriz para acelerar el proceso.

    //the arrays 
    var arabicFormat = [1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000];
    var romanFormat = ['I', 'IV', 'V', 'IX', 'X', 'XL', 'L', 'XC', 'C', 'CD', 'D', 'CM', 'M'];
    function convertToRoman(num) {
    //the recursion will stop here returning a blank
    if (num === 0){
    return '';
    }
    var returnValue = [];
    //this is the main For loop of the function
    for (var i=0; i < arabicFormat.length; i++){
    if (num >= arabicFormat[i]){
    //empty the array on every iteration until it gets to the final number
    returnValue = [];
    //store the current highest matched number in the array
    returnValue.push(romanFormat[i]);
    } 
    }
    //get the correct resulting format 
    returnValue = returnValue.join();
    //get the highest matched number value
    var whatIndex = romanFormat.indexOf(returnValue);
    var substractValue = arabicFormat[whatIndex];
    //here the recursion happens
    return returnValue + convertToRoman(num - substractValue);
    }
  50. 0

    Traté de hacer esto mediante la asignación de un array de números arábigos a un array de pares de romano. La desagradable 3-nivel ternaries podría ser reemplazado por si() {} else{} los bloques para hacerlos más legibles. Se trabaja a partir de 1 a 3999, pero podría ampliarse:

    function romanize(num) {
    if(num > 3999 || num < 1) return 'outside range!';
    const roman = [ ['M', ''], [ 'C', 'D' ], [ 'X', 'L' ], [ 'I', 'V' ] ];
    const arabic = num.toString().padStart(4, '0').split('');
    return arabic.map((e, i) => {
    return (
    e < 9 ? roman[i][1].repeat(Math.floor(e / 5)) : ''
    ) + (
    e % 5 < 4
    ? roman[i][0].repeat(Math.floor(e % 5))
    : e % 5 === 4 && Math.floor(e / 5) === 0
    ? roman[i][0] + roman[i][1]
    : Math.floor(e / 5) === 1
    ? roman[i][0] + roman[i - 1][0]
    : ''
    );
    }).join('');
    }
  51. 0

    Hay varias maneras de lograr esto. Yo, personalmente, prefiero el uso de objetos y iterar a través de los pares clave-valor:

    const solution=(n)=>{
    const romanLetters ={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 romanNumber ='';
    let valuesArr = Object.values(romanLetters);
    for(let i in valuesArr){
    while (n - valuesArr[i] >= 0){
    romanNumber+=Object.keys(romanLetters)[i]; 
    n-=valuesArr[i];
    }
    }
    return romanNumber;
    }
  52. 0

    Probablemente la solución más sencilla:

    JS:

    rome = n => {
    b=0
    s=''
    for(a=5; n; b++,a^=7)
    for(o=n%a, n=n/a^0;o--;)
    s='IVXLCDM'[o>2?b+n-(n&=-2)+(o=1):b]+s
    return s
    }
    r = [rome(892),rome(3999)];
    console.log(r);

    No puedo tomar el crédito. Este es vetalperko del solución en CodeSignal.

  53. 0

    Me gustó mucho la solución por jaggedsoft pero yo no podía responder porque mi representante es DEMASIADO BAJA 🙁 🙁

    Me rompió hacia abajo a explicar un poco para los que no lo entienden. Espero que ayude a alguien.

    function convertToRoman(num) {
    var 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},roman = '',i;
    for ( i in lookup ) {
    while ( num >= lookup[i] ) { //while input is BIGGGER than lookup #..1000, 900, 500, etc.
    roman += i; //roman is set to whatever i is (M, CM, D, CD...)
    num -= lookup[i]; //takes away the first num it hits that is less than the input
    //in this case, it found X:10, added X to roman, then took away 10 from input
    //input lowered to 26, X added to roman, repeats and chips away at input number
    //repeats until num gets down to 0. This triggers 'while' loop to stop.    
    }
    }
    return roman;
    }
    console.log(convertToRoman(36));
  54. 0

    Aquí está mi código,Espero que esta ayuda:

    JS:

    function convertToRoman(num) {
    let numArr = [];//[M,D,C,L,X,V,I]
    let numStr = "";
    //get num Array
    numArr.push(parseInt(num / 1000));
    num %= 1000;
    numArr.push(parseInt(num / 500));
    num %= 500;
    numArr.push(parseInt(num / 100));
    num %= 100;
    numArr.push(parseInt(num / 50));
    num %= 50;
    numArr.push(parseInt(num / 10));
    num %= 10;
    numArr.push(parseInt(num / 5));
    num %= 5;
    numArr.push(num);
    //cancat num String
    for(let i = 0; i < numArr.length; i++) {
    switch(i) {
    case 0://M
    for(let j = 0; j < numArr[i]; j++) {
    numStr = numStr.concat("M");
    }
    break;
    case 1://D
    switch(numArr[i]) {
    case 0:
    break;
    case 1:
    if(numArr[i + 1] === 4) {
    numStr = numStr.concat("CM");
    i++;
    }else {
    numStr = numStr.concat("D");
    }
    break;
    }
    break;
    case 2://C
    switch(numArr[i]) {
    case 0:
    break;
    case 1:
    numStr = numStr.concat("C");
    break;
    case 2:
    numStr = numStr.concat("CC");
    break;
    case 3:
    numStr = numStr.concat("CCC");
    break;
    case 4:
    numStr = numStr.concat("CD");
    break;
    }
    break;
    case 3://L
    switch(numArr[i]) {
    case 0:
    break;
    case 1:
    if(numArr[i + 1] === 4) {
    numStr = numStr.concat("XC");
    i++;
    }else {
    numStr = numStr.concat("L");
    }
    break;
    }
    break;
    case 4://X
    switch(numArr[i]) {
    case 0:
    break;
    case 1:
    numStr = numStr.concat("X");
    break;
    case 2:
    numStr = numStr.concat("XX");
    break;
    case 3:
    numStr = numStr.concat("XXX");
    break;
    case 4:
    numStr = numStr.concat("XL");
    break;
    }
    break;
    case 5://V
    switch(numArr[i]) {
    case 0:
    break;
    case 1:
    if(numArr[i + 1] === 4) {
    numStr = numStr.concat("IX");
    i++;
    }else {
    numStr = numStr.concat("V");
    }
    break;
    }
    break;
    case 6://I
    switch(numArr[i]) {
    case 0:
    break;
    case 1:
    numStr = numStr.concat("I");
    break;
    case 2:
    numStr = numStr.concat("II");
    break;
    case 3:
    numStr = numStr.concat("III");
    break;
    case 4:
    numStr = numStr.concat("IV");
    break;
    }
    break;
    }
    }
    console.log(numStr);
    return numStr;
    }
    convertToRoman(3999);

  55. 0

    Esta es mi solución con un solo bucle

    function convertToRoman(num) {
    var roman = {
    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 romanNum = "";
    for(key in roman){
    var check = num>=roman[key];
    if(check){
    console.log(romanNum);
    romanNum += key;
    num-= roman[key]; 
    }
    }
    return romanNum
    }
    convertToRoman(150);
  56. 0

    Esta solución sólo se ejecuta un bucle y tiene el mínimo objeto de asignar números a las letras romanas

    function RomantoNumeral(r){
    let result = 0,
    keys = {M:1000, D:500, C:100, L:50, C:100, L:50, X:10, V:5, I:1},
    order = Object.keys(keys),
    rom = Array.from(r) 
    rom.forEach((e, i)=>{
    if( i  < rom.length -1 && order.indexOf(e) > order.indexOf(rom[i+1])){
    result -= keys[e]
    } else {
    result +=keys[e]
    }
    })  
    return result
    }
    RomantoNumeral('MMDCCCXXXVII') #2837
  57. 0

    Bucles pueden ser más elegante, pero me parece difícil de leer. Es más o menos codificado versión que es fácil en los ojos. Como comprender la primera línea, el resto es una obviedad.

    function romanNumeralGenerator (int) {
    let roman = '';
    roman +=  'M'.repeat(int / 1000);  int %= 1000; 
    roman += 'CM'.repeat(int / 900);   int %= 900; 
    roman +=  'D'.repeat(int / 500);   int %= 500;  
    roman += 'CD'.repeat(int / 400);   int %= 400;
    roman +=  'C'.repeat(int / 100);   int %= 100;
    roman += 'XC'.repeat(int / 90);    int %= 90;
    roman +=  'L'.repeat(int / 50);    int %= 50;
    roman += 'XL'.repeat(int / 40);    int %= 40;
    roman +=  'X'.repeat(int / 10);    int %= 10;
    roman += 'IX'.repeat(int / 9);     int %= 9;
    roman +=  'V'.repeat(int / 5);     int %= 5;
    roman += 'IV'.repeat(int / 4);     int %= 4;
    roman +=  'I'.repeat(int);
    return roman;
    }
  58. -1

    Escribí esto desde cero para freecodecamp reto. Espero que esto ayude a alguien.

    JS:

    function convertToRoman(num) {
    var nums = [0, 0, 0, 0];
    var numsRom = ["", "", "", ""];
    var nRom = {
    I: "I",
    V: "V",
    X: "X",
    L: "L",
    C: "C",
    D: "D",
    M: "M"
    };
    /*
    1,
    5,
    10,
    50,
    100,
    500,
    1000
    */
    var i;
    nums[0] = Math.floor(num / 1000);
    nums[1] = Math.floor((num - nums[0] * 1000) / 100);
    nums[2] = Math.floor((num - nums[0] * 1000 - nums[1] * 100) / 10);
    nums[3] = num - nums[0] * 1000 - nums[1] * 100 - nums[2] * 10;
    //1000
    for (i = 0; i < nums[0]; i++) {
    numsRom[0] += nRom.M;
    }
    //100
    switch (nums[1]) {
    case 1:
    case 2:
    case 3:
    for (i = 0; i < nums[1]; i++) {
    numsRom[1] += nRom.C;
    }
    break;
    case 4:
    numsRom[1] += nRom.C + nRom.D;
    break;
    case 5:
    numsRom[1] += nRom.D;
    break;
    case 6:
    case 7:
    case 8:
    numsRom[1] += nRom.D;
    for (i = 0; i < nums[1] - 5; i++) {
    numsRom[1] += nRom.C;
    }
    break;
    case 9:
    numsRom[1] += nRom.C + nRom.M;
    }
    //10
    switch (nums[2]) {
    case 1:
    case 2:
    case 3:
    for (i = 0; i < nums[2]; i++) {
    numsRom[2] += nRom.X;
    }
    break;
    case 4:
    numsRom[2] += nRom.X + nRom.L;
    break;
    case 5:
    numsRom[2] += nRom.L;
    break;
    case 6:
    case 7:
    case 8:
    numsRom[2] += nRom.L;
    for (i = 0; i < nums[2] - 5; i++) {
    numsRom[2] += nRom.X;
    }
    break;
    case 9:
    numsRom[2] += nRom.X + nRom.C;
    }
    //1
    switch (nums[3]) {
    case 1:
    case 2:
    case 3:
    for (i = 0; i < nums[3]; i++) {
    numsRom[3] += nRom.I;
    }
    break;
    case 4:
    numsRom[3] += nRom.I + nRom.V;
    break;
    case 5:
    numsRom[3] += nRom.V;
    break;
    case 6:
    case 7:
    case 8:
    numsRom[3] += nRom.V;
    for (i = 0; i < nums[3] - 5; i++) {
    numsRom[3] += nRom.I;
    }
    break;
    case 9:
    numsRom[2] += nRom.I + nRom.X;
    }
    return numsRom.join("");
    }
    console.log("Number: " + 1234 + " is " + convertToRoman(1234));

Dejar respuesta

Please enter your comment!
Please enter your name here