Skip to content

Instantly share code, notes, and snippets.

@jazlalli
Last active December 11, 2015 21:39
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 jazlalli/4663914 to your computer and use it in GitHub Desktop.
Save jazlalli/4663914 to your computer and use it in GitHub Desktop.
Roman numeral generator - romanNumeralGenerator(inputNumber, outputString) is the main function that recurses to create the roman numeral representation on the integer supplied, albeit, slightly incorrectly. - amendOutput(inputString) corrects the answer to account for the special cases (e.g. IIII -> IV)
var converter = (function () {
'use strict';
var romanNumeralsArray = [
{roman: 'I', number: 1},
{roman: 'V', number: 5},
{roman: 'X', number: 10},
{roman: 'L', number: 50},
{roman: 'C', number: 100},
{roman: 'D', number: 500},
{roman: 'M', number: 1000}
],
length = romanNumeralsArray.length,
outputString = '',
inputNumber = 0;
//helper to get index of item in roman numeral array
function getIndexOfLetterInNumeralsArray(strValue) {
var i, obj;
for (i = 0; i < length; i += 1) {
if (romanNumeralsArray[i].roman === strValue) {
obj = romanNumeralsArray[i];
return romanNumeralsArray.indexOf(obj);
}
}
return -1;
}
function romanNumeralGenerator(intVal, stringVal) {
var i,
matchedNumberIndex,
matchedNumber = 0;
//break condition for the recursive calls
if (intVal < 1 || intVal > 3999) {
return stringVal;
}
//iterate through numerals array to find the highest number that goes into the input
for (i = 0; i < length; i += 1) {
if (romanNumeralsArray[i].number <= intVal && romanNumeralsArray[i].number > matchedNumber) {
matchedNumber = romanNumeralsArray[i].number;
matchedNumberIndex = i;
}
}
//add corresponding letter to the answer and subtract the number from the input
stringVal += romanNumeralsArray[matchedNumberIndex].roman;
intVal = intVal - matchedNumber;
//recurse
stringVal = romanNumeralGenerator(intVal, stringVal);
return stringVal;
}
function amendOutput(input) {
var i,
output = '',
match = input.match(/(.)\1{3}/g),
allMatches,
matchedCharacter,
//info from the input string
repeatingCharFirstPosition,
repeatingCharPreceedingChar,
//indices of the above characters in the numerals array
rindex, pindex;
//is there a character repeating 4 times?
if (match) {
allMatches = input.match(/(.)\1{3}/g).toString().split(',');
for (i = 0; i < allMatches.length; i += 1) {
matchedCharacter = allMatches[i].split('')[0],
repeatingCharFirstPosition = input.indexOf(matchedCharacter),
repeatingCharPreceedingChar = input.split('')[repeatingCharFirstPosition - 1],
rindex = getIndexOfLetterInNumeralsArray(matchedCharacter),
pindex = getIndexOfLetterInNumeralsArray(repeatingCharPreceedingChar);
//if the character preceeding the repeating one is the next numeral up
if (pindex === (rindex + 1)) {
output = output.substring(0, repeatingCharFirstPosition - 1);
//if this is the first pass through fixing the string
if (!output) {
output = input.substring(0, repeatingCharFirstPosition - 1);
}
output += matchedCharacter + romanNumeralsArray[rindex + 2].roman;
} else {
output += matchedCharacter + romanNumeralsArray[rindex + 1].roman;
}
}
input = output;
}
return input;
}
return {
romanNumeralGenerator: function (inputInt) {
var answer = '';
answer = romanNumeralGenerator(inputInt, answer);
answer = amendOutput(answer);
return answer;
}
}
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment