Skip to content

Instantly share code, notes, and snippets.

@ancyrweb
Created May 28, 2024 15:48
Show Gist options
  • Save ancyrweb/0a6e24665aa7b8c25e598a63a301a9c1 to your computer and use it in GitHub Desktop.
Save ancyrweb/0a6e24665aa7b8c25e598a63a301a9c1 to your computer and use it in GitHub Desktop.
Roman Numerals, in TypeScript
class Roman {
constructor(private readonly str: string) {}
private static LOOKUP = {
I: 1,
V: 5,
X: 10,
L: 50,
C: 100,
D: 500,
M: 1000,
};
toNumber() {
return this.str.split('').reduce((acc, _, i) => acc + this.valueOf(i), 0);
}
private valueOf(i: number) {
return Roman.LOOKUP[this.str[i]] * this.factor(i);
}
factor(i: number) {
return Roman.LOOKUP[this.str[i + 1]] > Roman.LOOKUP[this.str[i]] ? -1 : 1;
}
}
const of = (str: string) => new Roman(str).toNumber();
test('I = 1', () => {
expect(of('I')).toBe(1);
});
test('II = 2', () => {
expect(of('II')).toBe(2);
});
test('III = 3', () => {
expect(of('III')).toBe(3);
});
test('V = 5', () => {
expect(of('V')).toBe(5);
});
test('IV = 4', () => {
expect(of('IV')).toBe(4);
});
test('X = 10', () => {
expect(of('X')).toBe(10);
});
test('IX = 9', () => {
expect(of('IX')).toBe(9);
});
test('L = 50', () => {
expect(of('L')).toBe(50);
});
test('XL = 40', () => {
expect(of('XL')).toBe(40);
});
test('C = 100', () => {
expect(of('C')).toBe(100);
});
test('XC = 90', () => {
expect(of('XC')).toBe(90);
});
test('D = 500', () => {
expect(of('D')).toBe(500);
});
test('M = 1000', () => {
expect(of('M')).toBe(1000);
});
test('Various integrations', () => {
expect(of('LXXXVIII')).toBe(88);
expect(of('XCVIII')).toBe(98);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment