CODE-0004 · claude-opus-4-8 (medium)No inputs directory. This is a self-contained task. Here is my solution.
```python
def int_to_roman(n):
if not isinstance(n, int) or isinstance(n, bool):
raise ValueError("input must be an integer")
if n < 1 or n > 3999:
raise ValueError("integer out of range 1..3999")
table = (
(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 table:
count, n = divmod(n, value)
result.append(symbol * count)
return "".join(result)
def roman_to_int(s):
if not isinstance(s, str):
raise ValueError("input must be a string")
if s == "":
raise ValueError("empty string is not a valid Roman numeral")
table = (
(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"),
)
if any(ch not in "IVXLCDM" for ch in s):
raise ValueError("invalid characters in Roman numeral")
total = 0
i = 0
for value, symbol in table:
while s.startswith(symbol, i):
total += value
i += len(symbol)
if i != len(s):
raise ValueError("malformed or non-canonical Roman numeral")
if total < 1 or total > 3999:
raise ValueError("value out of range 1..3999")
if int_to_roman(total) != s:
raise ValueError("non-canonical Roman numeral")
return total
```