Skip to content

Instantly share code, notes, and snippets.

@claudioc
Created December 2, 2012 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save claudioc/4188260 to your computer and use it in GitHub Desktop.
Save claudioc/4188260 to your computer and use it in GitHub Desktop.
Roman <=> Integer (JavaScript)
var RomanEmpire = {
emperor: "Claudio Cicali",
numbers: {
letters: [ "M", "D", "C", "L", "X", "V", "I" ],
integers: [ "1000", "500", "100", "50", "10", "5", "1" ]
},
romanFor: function(integer) {
return this.numbers.letters[this.numbers.integers.indexOf("" + integer)];
},
integerFor: function(roman) {
return parseInt(this.numbers.integers[this.numbers.letters.indexOf(roman)], 10) || 0;
}
}
RomanEmpire.Number = function(repr) {
var value = {
integer: 0,
roman: ''
};
var outputType;
if (isNaN(repr)) {
outputType = 'integer';
value.integer = parseRoman(repr, 0);
value.roman = repr;
if (parseInteger("" + value.integer) != value.roman) {
throw ("Duo numeri non equatur! " + (value.roman) + " != " + (value.integer));
}
} else {
outputType = 'roman';
value.roman = parseInteger("" + repr);
value.integer = repr;
if (parseRoman(value.roman, 0) != value.integer) {
throw ("Duo numeri non equatur! " + (value.integer) + " != " + (value.roman));
}
}
function parseRoman(roman, acc) {
if (!roman[0]) {
return acc;
}
var d0 = RomanEmpire.integerFor(roman[0])
, d1 = RomanEmpire.integerFor(roman[1]);
switch ( true ) {
case d1 <= d0:
return parseRoman( roman.substr( 1 ), acc + d0 );
case d1 > d0:
return parseRoman( roman.substr( 2 ), acc + ( d1 - d0 ) );
}
}
function parseInteger(integer) {
var mult;
var number = "";
var tmp;
while (integer.length > 0) {
if (integer[0] > 0) {
mult = Math.pow(10, integer.length - 1);
tmp = parseInt((integer[0] * mult));
/* This is for "special, edge cases".
* Example for "4": mult is 1 and and K esists so that K - 1 = 4. In that case K is 5 so I use R(1) + R(5) which is IV
* Example for "400": mult is 100 and and K esists so that K - 100 = 400. In that case K is 500 so I use R(100) + R(500) which is CD
*/
if (!RomanEmpire.numbers.integers.some(function(value) {
if ( (value - tmp ) == mult ) {
number += (RomanEmpire.romanFor(mult) + RomanEmpire.romanFor(value));
return true;
}
return false;
})) {
RomanEmpire.numbers.integers.forEach(function(value) {
while ((tmp - value) >= 0) {
tmp -= value;
number += RomanEmpire.romanFor(value);
}
});
}
}
integer = integer.substr(1);
}
return number;
}
return {
converted: function() {
return value[outputType];
}
};
}
var lines = [], n;
process.stdin.resume();
process.stdin.on('data', function(chunk){
lines.push(chunk.toString());
});
process.stdin.on('end', function(){
lines.join("").split("\n").forEach(function(number) {
n = new RomanEmpire.Number(number);
console.log(n.converted());
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment