Number to Roman Numeral

Posted on

Problem

var romanArray = [];
var toRoman = {

    analyze: function(number){
        romanArray = [];
        if (number >= 1000) {
            return this.thousands(number);
        }else if (number >= 100){
            return this.hundreds(number);
        }else if (number >= 10) {
            return this.tens(number);
        }else{
            return this.last_number(number);
        }
    },

    thousands: function(number){
        var remainder = number % 1000;
        var thousands = Math.floor(number / 1000);
        for(var e = 0; e < thousands; e++) {
            romanArray.push('M');
        }
        return this.hundreds(remainder);
    },

    hundreds: function(number){
        var remainder = number % 100;
        var hundreds = Math.floor(number / 100);
        if (hundreds === 4){
            romanArray.push('CD');
        }else if(hundreds === 9){
            romanArray.push('CM');
        }else if(hundreds >= 5 && hundreds < 9){
            romanArray.push('D');
            for(var i = 0; i < (hundreds % 5); i++) {
                romanArray.push('C');
            }
        }else if (hundreds > 0 && hundreds < 4){
            for(var e = 0; e < hundreds; e++) {
                romanArray.push('C');
            }
        }else{

        }
        return this.tens(remainder);
    },

    tens: function(number){
        var remainder = number % 10;
        var tens = Math.floor(number / 10);
        if (tens === 4){
            romanArray.push('XL');
        }else if(tens === 9){
            romanArray.push('XC');
        }else if(tens >= 5 && tens < 9){
            romanArray.push('L');
            for(var i = 0; i < (tens % 5); i++) {
                romanArray.push('X');
            }
        }else if (tens > 0 && tens < 4){
            for(var e = 0; e < tens; e++) {
                romanArray.push('X');
            }
        }else{

        }
        return this.last_number(remainder);
    },

    last_number: function (number){
        if (number === 4){
            romanArray.push('IV');
        }else if(number === 9){
            romanArray.push('IX');
        }else if(number >= 5 && number < 9){
            romanArray.push('V');
            var remainder = number % 5;
            for(var i = 0; i < remainder; i++) {
                romanArray.push('I');
            }
        }else if (number > 0 && number < 4){
            for(var e = 0; e < number; e++) {
                romanArray.push('I');
            }
        }else{

        }
        return romanArray.join('');
    }
};

console.log(toRoman.analyze(1000));
console.log(toRoman.analyze(2999));
console.log(toRoman.analyze(2555));

I’m wondering if this JavaScript can be refactored using some sort of base/template function.
For Example:

base_function: function (number, four, nine, five, one){
    if (number === 4){
        romanArray.push(four);
    }else if(number === 9){
        romanArray.push(nine);
    }else if(number >= 5 && number < 9){
        romanArray.push(five);
        var remainder = number % 5;
        for(var i = 0; i < remainder; i++) {
            romanArray.push(one);
        }
    }else if (number > 0 && number < 4){
        for(var e = 0; e < number; e++) {
            romanArray.push(one);
        }
    }else{

    }
    return romanArray;
},

How can I improve this code?

Solution

Normally, asking for code to be written is against the rules of this website. However, since you already have a working solution, an idea of where you want to go, and an independent solution from @Stuart, I suppose there’s no harm in just finishing it for you:

hundreds: function(number) {
    base_function(Math.floor(number / 100), 'CD', 'CM', 'D', 'C');
    return this.tens(number % 100);
},

// etc.

You may be aware that there are simpler answers to this problem, such as:

function toRoman(n) {
    var r = '',
        decimals = [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'];
    for (var i = 0; i < decimals.length; i++) {
        while (n >= decimals[i]) {
            r += roman[i];
            n -= decimals[i];
        }
    }
    return r;
}

Bearing this in mind it might be useful to explain what exactly you are trying to achieve with your refactoring? E.g. is it to practice using more complicated language patterns?

Leave a Reply

Your email address will not be published. Required fields are marked *