Skip to content

Instantly share code, notes, and snippets.

@patrickodacre
Created July 29, 2016 10:55
Show Gist options
  • Save patrickodacre/d154d61c311e85511dfe10ba957f694f to your computer and use it in GitHub Desktop.
Save patrickodacre/d154d61c311e85511dfe10ba957f694f to your computer and use it in GitHub Desktop.

Revisions

  1. Patrick O'Dacre created this gist Jul 29, 2016.
    105 changes: 105 additions & 0 deletions romanNumeralConverter.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,105 @@
    /*
    * https://www.freecodecamp.com/challenges/roman-numeral-converter
    * */

    /**
    * My original solution.
    *
    * @param {integer} num Number to transform.
    * @returns {string} Roman numeral equivalent.
    */
    function convertToRoman(num) {

    /*
    * Shamelessly, I got the idea for the reference arrays on the Github
    * solutions wiki.
    *
    * This one really stumped me.
    * */
    var decimalArrReference = [
    1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1
    ],
    romanNumeralArrReference = [
    'M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'
    ];

    /*
    * Using Array.prototype.reduce() to iterate over the reference array
    * felt cleaner than using a for loop or a while loop to iterate over the decimalArrReference array.
    *
    * But just to make sure, I clocked the performance and was disappointed
    * that my favored reduce() clocked far slower. I'm not surprised, though.
    * */
    var romanizedNumberArr = decimalArrReference.reduce(function (accumulator, decNum, idx) {

    while (decNum <= num) {
    accumulator.push(romanNumeralArrReference[idx]);
    num -= decNum;
    }

    return accumulator;

    }, []);

    return romanizedNumberArr.join('');
    }

    convertToRoman(36);

    /**
    * "Basic" Solution found on Github.
    *
    * Often the "basic" solutions tend to be the best.
    *
    * You can see the original solution at the provided link.
    * Hats off to the contributors there.
    *
    * @link https://github.com/FreeCodeCamp/FreeCodeCamp/wiki/Algorithm-Roman-Numeral-Converter
    * @param {integer} num Number to transform.
    * @returns {string} Roman numeral equivalent.
    */
    var convertToRomanTwo = function (num) {

    var decimalValue = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1],
    romanNumeral = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'],
    decLength = decimalValue.length, // store length here so we don't have to recalculate it on every loop.
    idx = 0;

    var romanized = '';

    /*
    * Loop over every value in decimalValue array.
    *
    * I tend to favor while loops over for loops because
    * they clock a bit faster.
    * */
    while (idx < decLength) {

    /*
    * Continue to add the corresponding
    * romanNumeral to the converted string
    * until the current decimalValue doesn't
    * fit into the num any more.
    * */
    while (decimalValue[idx] <= num) {

    /*
    * Concat the roman numeral to the converted string.
    * */
    romanized += romanNumeral[idx];

    /*
    * continue to reduce the num by the decimalValue
    * otherwise we'd get an infinite loop.
    * */
    num -= decimalValue[idx];
    }

    // Move onto the next value in decimalValue array.
    idx ++;
    }

    return romanized;
    }

    convertToRomanTwo(36);