IntegerToRoman
Problem
https://leetcode.com/problems/integer-to-roman/
Seven different symbols represent Roman numerals with the following values:
Symbol |
Value |
|---|---|
I |
1 |
V |
5 |
X |
10 |
L |
50 |
C |
100 |
D |
500 |
M |
1000 |
Roman numerals are formed by appending the conversions of decimal place values from highest to lowest. Converting a decimal place value into a Roman numeral has the following rules:
If the value does not start with 4 or 9, select the symbol of the maximal value that can be subtracted from the input, append that symbol to the result, subtract its value, and convert the remainder to a Roman numeral.
If the value starts with 4 or 9 use the subtractive form representing one symbol subtracted from the following symbol, for example, 4 is 1 (
I) less than 5 (V):IVand 9 is 1 (I) less than 10 (X):IX. Only the following subtractive forms are used: 4 (IV), 9 (IX), 40 (XL), 90 (XC), 400 (CD) and 900 (CM).Only powers of 10 (
I,X,C,M) can be appended consecutively at most 3 times to represent multiples of 10. You cannot append 5 (V), 50 (L), or 500 (D) multiple times. If you need to append a symbol 4 times use the subtractive form.
Given an integer, convert it to a Roman numeral.
Example 1:
Input: num = 3749
Output: “MMMDCCXLIX”
Explanation:
3000 = MMM as 1000 (M) + 1000 (M) + 1000 (M)
700 = DCC as 500 (D) + 100 (C) + 100 (C)
40 = XL as 10 (X) less of 50 (L)
9 = IX as 1 (I) less of 10 (X)
Note: 49 is not 1 (I) less of 50 (L) because the conversion is based on decimal places
Example 2:
Input: num = 58
Output: “LVIII”
Explanation:
50 = L
8 = VIII
Example 3:
Input: num = 1994
Output: “MCMXCIV”
Explanation:
1000 = M
900 = CM
90 = XC
4 = IV
Constraints:
1 <= num <= 3999
Solution
Observe that the Roman numeral for a number is composed of the Roman numerals
for each digit. Suppose our digit is in the ones place. Then, the Roman
numberal is ‘I’ repeated digit times if digit is less than 4 and ‘IV’
if digit is 4. For digit between 5 and 8, the Roman numeral is ‘V’
followed by ‘I’ digit - 5 times. Finally, if digit is 9, the Roman
numeral is ‘IX’. For digits in the tens, hundreds, and thousands places, the
pattern holds, but with different symbols for ones, fives, and tens.
Pattern
Hash Table, Math, String
Code
def intToRoman(num: int) -> str:
"""Convert an integer between 0 and 3999 to a Roman numeral.
"""
thousands_digit = (num % 10000) // 1000
hundreds_digit = (num % 1000) // 100
tens_digit = (num % 100) // 10
ones_digit = num % 10
symbols = ['I', 'V', 'X', 'L', 'C', 'D', 'M', '?', '!']
thousands_roman = roman_subnumeral(thousands_digit, *symbols[6:9])
hundreds_roman = roman_subnumeral(hundreds_digit, *symbols[4:7])
tens_roman = roman_subnumeral(tens_digit, *symbols[2:5])
ones_roman = roman_subnumeral(ones_digit, *symbols[:3])
return thousands_roman + hundreds_roman + tens_roman + ones_roman
def roman_subnumeral(digit, symbol, five_symbol, ten_symbol):
"""Generate the Roman sub-numberal for a single digit.
"""
if digit < 4:
return digit * symbol
elif digit == 4:
return symbol + five_symbol
elif 5 <= digit < 9:
return five_symbol + (digit - 5) * symbol
elif digit == 9:
return symbol + ten_symbol
Test
>>> from IntegerToRoman import intToRoman
>>> intToRoman(3)
'III'
>>> intToRoman(58)
'LVIII'
>>> intToRoman(1994)
'MCMXCIV'
- IntegerToRoman.intToRoman(num: int) str
Convert an integer between 0 and 3999 to a Roman numeral.
- IntegerToRoman.roman_subnumeral(digit, symbol, five_symbol, ten_symbol)
Generate the Roman sub-numberal for a single digit.