CODE-0004 · claude-sonnet-4-6 (high)def int_to_roman(n):
if not isinstance(n, int) or isinstance(n, bool) or n < 1 or n > 3999:
raise ValueError(f"Input must be an integer in range 1..3999, got {n!r}")
values = [
1000, 900, 500, 400,
100, 90, 50, 40,
10, 9, 5, 4,
1,
]
symbols = [
'M', 'CM', 'D', 'CD',
'C', 'XC', 'L', 'XL',
'X', 'IX', 'V', 'IV',
'I',
]
result = []
for value, symbol in zip(values, symbols):
while n >= value:
result.append(symbol)
n -= value
return ''.join(result)
def roman_to_int(s):
if not s:
raise ValueError("Empty string is not a valid Roman numeral")
roman_vals = {
'I': 1, 'V': 5, 'X': 10, 'L': 50,
'C': 100, 'D': 500, 'M': 1000,
}
for ch in s:
if ch not in roman_vals:
raise ValueError(f"Invalid character {ch!r} in Roman numeral {s!r}")
total = 0
prev = 0
for ch in reversed(s):
curr = roman_vals[ch]
if curr < prev:
total -= curr
else:
total += curr
prev = curr
if total < 1 or total > 3999:
raise ValueError(f"Roman numeral {s!r} evaluates to {total}, out of range 1..3999")
canonical = int_to_roman(total)
if canonical != s:
raise ValueError(
f"{s!r} is not a canonical Roman numeral (canonical form is {canonical!r})"
)
return total