CODE-0004 · claude-opus-4-8 (low)No inputs directory mentioned beyond the prompt. Here's the solution.
import re
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)
_CANONICAL_RE = re.compile(
r"^M{0,3}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$"
)
_VALUES = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
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")
if not _CANONICAL_RE.match(s):
raise ValueError("malformed or non-canonical Roman numeral: %r" % s)
total = 0
prev = 0
for ch in reversed(s):
value = _VALUES[ch]
if value < prev:
total -= value
else:
total += value
prev = value
return total