Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions Conversions/RomanToNumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* @function romanToNumber
* @description Converts a Roman numeral string to its decimal number.
* @param {string} roman - A valid Roman numeral string
* @returns {number} - The decimal representation of the Roman numeral
* @see https://en.wikipedia.org/wiki/Roman_numerals
* @example romanToNumber("III") => 3
* @example romanToNumber("IX") => 9
* @example romanToNumber("MCMXCIV") => 1994
*/
const romanToNumber = (roman) => {
if (typeof roman !== 'string' || !/^[IVXLCDM]+$/.test(roman)) {
throw new TypeError('Input must be a valid Roman numeral string')
}
const romanValues = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000
}
let result = 0
for (let i = 0; i < roman.length; i++) {
const current = romanValues[roman[i]]
const next = romanValues[roman[i + 1]]
if (next && current < next) {
result -= current
} else {
result += current
}
}
return result
}

export { romanToNumber }
47 changes: 47 additions & 0 deletions Conversions/test/RomanToNumber.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { romanToNumber } from '../RomanToNumber.js'

describe('romanToNumber', () => {
test("romanToNumber('I') returns 1", () => {
expect(romanToNumber('I')).toBe(1)
})

test("romanToNumber('III') returns 3", () => {
expect(romanToNumber('III')).toBe(3)
})

test("romanToNumber('IV') returns 4", () => {
expect(romanToNumber('IV')).toBe(4)
})

test("romanToNumber('IX') returns 9", () => {
expect(romanToNumber('IX')).toBe(9)
})

test("romanToNumber('LVIII') returns 58", () => {
expect(romanToNumber('LVIII')).toBe(58)
})

test("romanToNumber('MCMXCIV') returns 1994", () => {
expect(romanToNumber('MCMXCIV')).toBe(1994)
})

test("romanToNumber('MMMCMXCIX') returns 3999", () => {
expect(romanToNumber('MMMCMXCIX')).toBe(3999)
})

test("romanToNumber('XL') returns 40", () => {
expect(romanToNumber('XL')).toBe(40)
})

test('throws TypeError for empty string', () => {
expect(() => romanToNumber('')).toThrow(TypeError)
})

test('throws TypeError for invalid characters', () => {
expect(() => romanToNumber('ABC')).toThrow(TypeError)
})

test('throws TypeError for non-string input', () => {
expect(() => romanToNumber(10)).toThrow(TypeError)
})
})
Loading