◀ THE GRIND — MATH & GEOMETRY

Roman to Integer

The drill: Convert a Roman numeral string back into the integer it represents — normally symbol values just add up left to right, except when a smaller symbol sits directly before a larger one, which signals subtraction instead.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

A Roman numeral arrives as a string built from the usual symbols — I, V, X, L, C, D, M — and the task is to convert it back into the plain integer it represents.

Most of the time, symbol values simply add together left to right. The exception is a smaller symbol sitting directly in front of a larger one, like IV or CM, which signals that the smaller value should be subtracted rather than added.

Every input is a numeral that could legitimately appear on a clock face or a page number — a valid Roman representation of some integer — so the conversion never has to guess at malformed symbol sequences.

EX 01
s = "VII"
7
PURELY ADDITIVE, NO SUBTRACTIVE PAIR
EX 02
s = "IX"
9
I BEFORE X
EX 03
s = "XL"
40
X BEFORE L
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

Summing every symbol's plain value overshoots exactly at the subtractive pairs — IV, IX, XL, XC, CD, CM — where a smaller symbol borrows meaning from the larger one right after it.

HINT 2 THE STRUCTURE

Each of those pairs, once summed naively, is off by precisely twice the smaller symbol's value — because it got added when it should have been subtracted.

HINT 3 ONE STEP FROM THE ANSWER

Either sum every symbol and then subtract 2× the smaller value at every place a symbol is immediately followed by a larger one, or walk left to right comparing each symbol only to its neighbor: add it normally, but subtract it when the next symbol outranks it.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE NEIGHBOR CHECKPATTERN · COMPARE WITH NEXT, ONE PASSs = "XIV"
X
I
V
RUNNING TOTAL
total0
STEP 1

X=10, I=1, V=5. Walk left to right, comparing each symbol only to its immediate neighbor.

STEP 1 / 6 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/roman-to-integer.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def romanToInt(self, s: str) -> int:
        values = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}

        total = 0
        for i, c in enumerate(s):
            v = values[c]
            if i + 1 < len(s) and v < values[s[i + 1]]:
                total -= v
            else:
                total += v
        return total
TIME O(N)SPACE O(1)PYTHON · RACE PACE · 12 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED