Last active
December 24, 2015 00:49
-
-
Save Sigmus/6719824 to your computer and use it in GitHub Desktop.
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
// | |
// Escolhe qual conversão utilizar dependendo do input | |
// | |
function converter(input) { | |
if (typeof input === 'number') { | |
return toRoman(input); | |
} | |
else { | |
return toIndu(input); | |
} | |
} | |
// | |
// Converte algarismos romanos para indu-arábicos | |
// | |
function toIndu(roman) { | |
var roman = roman.split(''); | |
var matrix = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000 }; | |
var order = ['I', 'V', 'X', 'L', 'C', 'D', 'M']; | |
// | |
// Validações | |
// | |
if (roman.some(nextFiveInvalid) || ! roman.every(nextBiggerValid) || roman.some(fourEquals)) { | |
return false; | |
} | |
// | |
// Engine da parada | |
// | |
function convert(indu, letter, index, roman) { | |
if (nextBigger(letter, index, roman)) { | |
indu -= matrix[letter]; | |
} | |
else { | |
indu += matrix[letter]; | |
} | |
return indu; | |
} | |
// | |
// Aplica engine para cada um dos algarismos | |
// | |
return roman.reduce(convert, 0); | |
// | |
// Fuções utilitárias | |
// | |
function hasNext(letter, index, roman) { | |
return typeof roman[index + 1] === 'string'; | |
} | |
function nextEqual(letter, index, roman) { | |
return hasNext(letter, index, roman) | |
&& roman[index] === roman[index + 1]; | |
} | |
function nextBigger(letter, index, roman) { | |
return hasNext(letter, index, roman) | |
&& matrix[roman[index + 1]] > matrix[roman[index]]; | |
} | |
function biggerValid(letter, index, roman) { | |
return (order.indexOf(roman[index + 1]) - order.indexOf(roman[index])) <= 2 | |
&& (matrix[roman[index + 1]] / matrix[letter]) != 2; | |
} | |
function nextBiggerValid(letter, index, roman) { | |
return ! nextBigger(letter, index, roman) | |
|| biggerValid(letter, index, roman); | |
} | |
function nextFiveInvalid(letter, index, roman) { | |
return nextEqual(letter, index, roman) | |
&& beginsWithFive(letter[index]); | |
} | |
function beginsWithFive(value) { | |
return new String(matrix[value])[0] === '5'; | |
} | |
function fourEquals(letter, index, roman) { | |
return nextEqual(letter, index, roman) | |
&& nextEqual(letter, index + 1, roman) | |
&& nextEqual(letter, index + 2, roman) | |
} | |
} | |
// | |
// Converte algarismos indu-arábicos para romanos | |
// | |
function toRoman(indu) { | |
var r1000 = convert(indu, 1000, 'M'); //console.log(r1000) | |
var r100 = convert(r1000.indu, 100, 'C', 'D', 'M'); //console.log(r100) | |
var r10 = convert(r100.indu, 10, 'X', 'L', 'C'); //console.log(r10) | |
var r1 = convert(r10.indu, 1, 'I', 'V', 'X'); //console.log(r1) | |
return r1000.roman + r100.roman + r10.roman + r1.roman; | |
function repeat(times, char) { | |
var snippet = ''; | |
for (var i = 0; i < times; i++) { | |
snippet += char; | |
} | |
return snippet; | |
} | |
function convert(indu, base, low, middle, high) { | |
var roman = '' | |
var times; | |
if (indu >= (1 * base) && indu < (4 * base)) { | |
times = Math.floor(indu / base); | |
roman = repeat(times, low); | |
indu -= (times * base); | |
} | |
else if (indu >= (4 * base) && indu < (5 * base)) { | |
times = Math.floor(indu / base); | |
roman = low + middle; | |
indu -= (times * base); | |
} | |
else if (indu === (5 * base)) { | |
roman = middle; | |
} | |
else if (indu > (5 * base) && indu < (9 * base)) { | |
times = Math.floor(indu / base) - 5; | |
roman = middle + repeat(times, low); | |
indu -= (times * base + (5 * base)); | |
} | |
else if (indu >= (9 * base) && indu < (10 * base)) { | |
roman = low + high; | |
indu -= (9 * base); | |
} | |
else if (indu === (10 * base)) { | |
roman = high; | |
} | |
return { | |
roman: roman, | |
indu: indu | |
}; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment