Skip to content

Instantly share code, notes, and snippets.

@meadsteve
Forked from jazlalli/gist:4663914
Last active December 11, 2015 21:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meadsteve/4665196 to your computer and use it in GitHub Desktop.
Save meadsteve/4665196 to your computer and use it in GitHub Desktop.
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 {
romanNumeralGenerator: romanNumeralGenerator
};
}
}());
@jazlalli
Copy link

I didn't make my code too clear...

You're on the right lines, but because I split the answer into 2 separate functions, and what with my lack of cleanliness in the code in general, the return should be like..

return {
  romanNumeralGenerator: function (input) {
    var answer = '';
    answer = romanNumeralGenerator(input, answer);
    answer = amendOutput(answer);
    return answer;
  }
}

@meadsteve
Copy link
Author

Ah that makes more sense. There's a small chance I only skimmed your code!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment