Created
December 2, 2012 11:16
-
-
Save claudioc/4188260 to your computer and use it in GitHub Desktop.
Roman <=> Integer (JavaScript)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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