I was looking at some code that included converting arabic to roman numerals, and it was all things like this:


function Level(i, v, x)
        {
        this.i = i;
        this.v = v;
        this.x = x
        }

levels = new Array();

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)
                {
                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 ''
// And so on

It all reminded me of fourth-grade BASIC. I should have been taking care of patients, but the challenge of writing a better converter kept me busy for a few minutes. Here's what I came up with:


var romanNumerals = [
	[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']
];
arabic2roman = function(n){
	var r = '';
	for (var i = 0; i < romanNumerals.length; ++i){
		for (var x = romanNumerals[i]; n >= x[0]; n -= x[0]) r += x[1];
	}
	return r;
}
roman2arabic = function(r){
	var n = 0;
	for (var i = 0; i < romanNumerals.length; ++i){
		for (var x = romanNumerals[i], l = x[1].length; r.substr(0,l) == x[1]; r = r.substr(l)) n += x[0];
	}
	return n;
}

Or, if you are willing to assume that your browser will always enumerate objects in order, you can make it a bit smaller:


var romanNumerals = { // assumes objects are enumerated in order
	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
};
arabic2roman = function(n){
	var r = '';
	for (var x in romanNumerals){
		for (var i = romanNumerals[x]; n >= i; n -= i) r += x;
	}
	return r;
}
roman2arabic = function(r){
	var n = 0, i = 0;
	for (var x in romanNumerals){
		for (var l = x.length; r.substr(i,l) == x; i+=l) n += romanNumerals[x];
	}
	return n;
}

Anyone out there with something smaller?

Edit 2013-07-31: this code is licensed under the MIT open source license.

Leave a Reply


Warning: Undefined variable $user_ID in /home/public/blog/wp-content/themes/evanescence/comments.php on line 75