CODE-0004 · deepseek-v4-pro (default)import re
def int_to_roman(n):
if not isinstance(n, int):
raise ValueError("Input must be an integer")
if not 1 <= n <= 3999:
raise ValueError("Integer must be between 1 and 3999")
mapping = [
(1000, 'M'), (900, 'CM'), (500, 'D'), (400, 'CD'),
(100, 'C'), (90, 'XC'), (50, 'L'), (40, 'XL'),
(10, 'X'), (9, 'IX'), (5, 'V'), (4, 'IV'), (1, 'I')
]
result = []
for value, symbol in mapping:
while n >= value:
result.append(symbol)
n -= value
return ''.join(result)
def roman_to_int(s):
if not isinstance(s, str) or len(s) == 0:
raise ValueError("Input must be a non-empty string")
# Canonical Roman numeral pattern (up to 3999)
pattern = r'^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$'
if not re.match(pattern, s):
raise ValueError("Invalid canonical Roman numeral")
roman_map = {
'I': 1, 'V': 5, 'X': 10, 'L': 50,
'C': 100, 'D': 500, 'M': 1000
}
total = 0
prev_value = 0
for ch in reversed(s):
value = roman_map[ch]
if value < prev_value:
total -= value
else:
total += value
prev_value = value
return total