[Toggle Comments]
package main // file: impl-001.go // Since Roman numerals are ASCII strings slicing and dicing them can be done // with regular slice operations without converting the string into // a slice of runes. // time: O(1) — There are a constant number of Roman numerals. // The highest possible value is: `MMMCMXCIX` // // space: O(1) func romanToInt(s string) int { values := map[string]int{ "I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000, } // Helper val := func(ix int) int { return values[string(s[ix])] } // One pass: // // If the current digit is greater than the next one add current, // and move on (XI -> 10 + 1). // // If the current digit is less than the next one, consider them as a unit // (`IX`, instead of `I and `X`) subtract (IX -> 10 - 1), and move the // pointer by two characters instead of one since you processed two chars // at once. total := 0 i := 0 lastIdx := len(s) - 1 for i <= lastIdx { current := val(i) // We are at the end. Nothing to subtract. Add this value to total. if i == lastIdx { total += current i++ continue } // The current digit is greater, we add it to the total. next := val(i + 1) if current >= next { total += current i++ continue } // The current digit is less than the next one. // We add `next - current` and move the pointer by two. // // For example, given `IX`, we think of it as a unit `IX` // that equals (10-1). And since `IX` occupies two spaces (instead of // one), we increment i by 2 (instead of 1). total += next - current i += 2 } return total } /* * \ * \\, * \\\,^,.,,. Zero to Hero * ,;7~((\))`;;,, <zerotohero.dev> * ,(@') ;)`))\;;', stay up to date, be curious: learn * ) . ),(( ))\;, * /;`,,/7),)) )) )\,, * (& )` (,((,((;( ))\, */