UNPKG

portunus

Version:

Converts from decimal numbers to roman numerals and the other way around.

112 lines 5.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const romanNumeralToDecimalValueMap = { 'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000, }; const decimalValueToRomanNumeralMap = Object.keys(romanNumeralToDecimalValueMap) .reduce((acc, currentValue) => { return Object.assign({ [romanNumeralToDecimalValueMap[currentValue]]: currentValue }, acc); }, {}); const sortedNumeralCollection = Object.keys(romanNumeralToDecimalValueMap) .sort((a, b) => romanNumeralToDecimalValueMap[b] - romanNumeralToDecimalValueMap[a]); const sortedDecimalCollection = Object.keys(decimalValueToRomanNumeralMap) .map(d => parseInt(d, 10)) .sort((a, b) => b - a); function isPortunusInput(input) { return typeof input === 'string' || typeof input === 'number'; } function portunus(input) { if (!isPortunusInput(input)) { return { error: `Provided input (${input}) not a valid portunus input.`, }; } if (typeof input === 'string') { return { convertedValue: portunusPeonNumeralToDecimal(input.toUpperCase()) }; } if (typeof input === 'number') { return { convertedValue: portunusPeonDecimalToNumeral(input) }; } return { error: `Something went wrong, perhaps input type check failed? I expect a number or string as input and got: ${typeof input}`, }; } exports.portunus = portunus; function portunusPeonNumeralToDecimal(numeral) { const numeralCollection = [].slice.call(numeral); return numeralCollection.reduce((acc, currentValue, currentIndex) => { const decimalValueForCurrentNumeral = romanNumeralToDecimalValueMap[currentValue]; const previousNumeral = numeralCollection[currentIndex - 1]; const decimalValueForPreviousNumeral = romanNumeralToDecimalValueMap[previousNumeral]; const subtractiveNotationPresent = !!decimalValueForPreviousNumeral && (decimalValueForPreviousNumeral < decimalValueForCurrentNumeral); let runningTally = acc + decimalValueForCurrentNumeral; if (subtractiveNotationPresent) { runningTally -= (decimalValueForPreviousNumeral * 2); } return runningTally; }, 0); } function portunusPeonDecimalToNumeral(integer) { const numeralWithoutSubtractiveNotation = sortedDecimalCollection .reduce((acc, currentDecimal) => { let numeral = decimalValueToRomanNumeralMap[currentDecimal]; let occurencesOfNumeral = Math.floor(integer / currentDecimal); integer -= (currentDecimal * occurencesOfNumeral); return `${acc}${numeral.repeat(occurencesOfNumeral)}`; }, ''); const numeralWithoutSubtractiveNotationCollection = [].slice.call(numeralWithoutSubtractiveNotation); let numeralWithSubtractiveNotationCollection = []; for (let i = 0; i < numeralWithoutSubtractiveNotationCollection.length; ++i) { const numeral = numeralWithoutSubtractiveNotationCollection[i]; const numeralRankIndex = sortedNumeralCollection.indexOf(numeral); const nextLowestRankingNumeralIndex = numeralRankIndex + 1; const nextLowestRankingNumeral = sortedNumeralCollection[nextLowestRankingNumeralIndex]; const nextHighestRankingNumeralIndex = numeralRankIndex - 1; const nextHighestRankingNumeral = sortedNumeralCollection[nextHighestRankingNumeralIndex]; const nextFourNumerals = [1, 2, 3, 4].map(indexOffset => numeralWithoutSubtractiveNotationCollection[i + indexOffset]); const nextThreeNumerals = nextFourNumerals.slice(0, 3); /*console.log({ numeralWithSubtractiveNotationCollection, numeral, numeralRankIndex, nextLowestRankingNumeral, nextLowestRankingNumeralIndex, nextHighestRankingNumeral, nextHighestRankingNumeralIndex, nextFourNumerals, nextThreeNumerals, });*/ if (!!nextHighestRankingNumeral) { if (nextThreeNumerals.every(n => sortedNumeralCollection.indexOf(n) === numeralRankIndex)) { /*console.log({ msg: 'here in next three', nextThreeNumerals, numeralWithoutSubtractiveNotation, });*/ numeralWithSubtractiveNotationCollection.push(`${numeral}${nextHighestRankingNumeral}`); i += 3; continue; } if (nextFourNumerals.every(n => sortedNumeralCollection.indexOf(n) === nextLowestRankingNumeralIndex)) { /*console.log({ msg: 'here in next four', nextFourNumerals, numeralWithoutSubtractiveNotation, });*/ numeralWithSubtractiveNotationCollection.push(`${nextLowestRankingNumeral}${nextHighestRankingNumeral}`); i += 4; continue; } } numeralWithSubtractiveNotationCollection.push(numeral); } ; return numeralWithSubtractiveNotationCollection.join(''); } //# sourceMappingURL=portunus.js.map