CODE-0004 · gemini-3.1-pro-preview (high)
def int_to_roman(n):
    if type(n) is not int:
        raise ValueError("Input must be an integer.")
    if not (1 <= n <= 3999):
        raise ValueError("Input must be between 1 and 3999 inclusive.")
    
    val = [
        1000, 900, 500, 400,
        100, 90, 50, 40,
        10, 9, 5, 4,
        1
    ]
    syb = [
        "M", "CM", "D", "CD",
        "C", "XC", "L", "XL",
        "X", "IX", "V", "IV",
        "I"
    ]
    roman_num = ""
    i = 0
    while n > 0:
        for _ in range(n // val[i]):
            roman_num += syb[i]
            n -= val[i]
        i += 1
    return roman_num

def roman_to_int(s):
    if type(s) is not str or not s:
        raise ValueError("Input must be a non-empty string.")
    
    mapping = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000}
    total = 0
    i = 0
    while i < len(s):
        if s[i] not in mapping:
            raise ValueError("Invalid character in Roman numeral.")
        val = mapping[s[i]]
        if i + 1 < len(s):
            if s[i+1] not in mapping:
                raise ValueError("Invalid character in Roman numeral.")
            next_val = mapping[s[i+1]]
            if next_val > val:
                total += next_val - val
                i += 2
                continue
        total += val
        i += 1
    
    if total < 1 or total > 3999:
        raise ValueError("Value out of range.")
    
    if int_to_roman(total) != s:
        raise ValueError("Not a canonical Roman numeral.")
        
    return total