A sequel to our previous effort, this time going the other way. That the greedy algorithm works here is not too surprising, but maybe there’s a way of concocting a variant of roman numerals where the greedy algorithm wouldn’t work? It’s basically the change-making algorithm. That it works is intuitive, perhaps, but it feels a bit unstable. If somehow we had to do something like this for production, I’d want to really spend out the time characterizing exactly why this works—why we can recast the whole subtractive thing as just a pile of coins. It’s sort of interesting, I guess…
def trySingleString(num, result, symbol, amount):
if num >= amount:
return num - amount, result + symbol
return num, result
def tryRepeatedString(num, result, symbol, amount):
while True:
num2, result2 = trySingleString(num, result, symbol, amount)
if num2 == num:
return num, result
num, result = num2, result2
class Solution:
def intToRoman(self, num: int) -> str:
assert num >= 0
result = ""
num, result = tryRepeatedString(num, result, "M", 1000)
num, result = tryRepeatedString(num, result, "CM", 900)
num, result = tryRepeatedString(num, result, "D", 500)
num, result = tryRepeatedString(num, result, "CD", 400)
num, result = tryRepeatedString(num, result, "C", 100)
num, result = tryRepeatedString(num, result, "XC", 90)
num, result = tryRepeatedString(num, result, "L", 50)
num, result = tryRepeatedString(num, result, "XL", 40)
num, result = tryRepeatedString(num, result, "X", 10)
num, result = tryRepeatedString(num, result, "IX", 9)
num, result = tryRepeatedString(num, result, "V", 5)
num, result = tryRepeatedString(num, result, "IV", 4)
num, result = tryRepeatedString(num, result, "I", 1)
return result