Skip to content

Commit 5de6f72

Browse files
authored
New feature: Support for converting numbers in a larger range.
To extend the current solution to support even larger ranges of numbers beyond 1,000,000, we can enhance the Roman numeral system to use additional notation for larger values. In Roman numerals, there is no native representation for numbers greater than 1,000,000.
1 parent 338cbaf commit 5de6f72

File tree

1 file changed

+34
-39
lines changed

1 file changed

+34
-39
lines changed

conversions/roman_numerals.py

+34-39
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,56 @@
11
ROMAN = [
2-
(1000, "M"),
3-
(900, "CM"),
4-
(500, "D"),
5-
(400, "CD"),
6-
(100, "C"),
7-
(90, "XC"),
8-
(50, "L"),
9-
(40, "XL"),
10-
(10, "X"),
11-
(9, "IX"),
12-
(5, "V"),
13-
(4, "IV"),
14-
(1, "I"),
2+
(1000000, "M_"), (900000, "C_M_"), (500000, "D_"), (400000, "C_D_"),
3+
(100000, "C_"), (90000, "X_C_"), (50000, "L_"), (40000, "X_L_"),
4+
(10000, "X_"), (9000, "I_X_"), (5000, "V_"), (4000, "I_V_"),
5+
(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"),
6+
(100, "C"), (90, "XC"), (50, "L"), (40, "XL"),
7+
(10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I")
158
]
16-
17-
189
def roman_to_int(roman: str) -> int:
1910
"""
20-
LeetCode No. 13 Roman to Integer
21-
Given a roman numeral, convert it to an integer.
22-
Input is guaranteed to be within the range from 1 to 3999.
23-
https://en.wikipedia.org/wiki/Roman_numerals
24-
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999}
11+
Convert a Roman numeral to an integer, supporting Vinculum notation (underscore _ represents 1000 times).
12+
LeetCode No. 13 Roman to Integer
13+
​    Given a roman numeral, convert it to an integer.
14+
​    Input is guaranteed to be within the range from 1 to 3999.
15+
​    https://en.wikipedia.org/wiki/Roman_numerals
16+
​    >>> all(roman_to_int(key) == value for key, value in tests.items())
17+
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999, "I_V_": 4000, "X_": 10000, "M_": 1000000}
2518
>>> all(roman_to_int(key) == value for key, value in tests.items())
2619
True
2720
"""
28-
vals = {"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000}
29-
total = 0
30-
place = 0
31-
while place < len(roman):
32-
if (place + 1 < len(roman)) and (vals[roman[place]] < vals[roman[place + 1]]):
33-
total += vals[roman[place + 1]] - vals[roman[place]]
34-
place += 2
21+
vals = {
22+
"I": 1, "V": 5, "X": 10, "L": 50, "C": 100, "D": 500, "M": 1000,
23+
"I_": 1000, "V_": 5000, "X_": 10000, "L_": 50000, "C_": 100000, "D_": 500000, "M_": 1000000
24+
}
25+
i, total = 0, 0
26+
while i < len(roman):
27+
if i + 1 < len(roman) and (roman[i:i+2] in vals): # 处理 `_` 记法
28+
total += vals[roman[i:i+2]]
29+
i += 2
3530
else:
36-
total += vals[roman[place]]
37-
place += 1
31+
total += vals[roman[i]]
32+
i += 1
3833
return total
39-
40-
41-
def int_to_roman(number: int) -> str:
34+
def int_to_roman(number: int) -> str:
4235
"""
43-
Given a integer, convert it to an roman numeral.
44-
https://en.wikipedia.org/wiki/Roman_numerals
45-
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999}
36+
Convert an integer to a Roman numeral, supporting Vinculum notation (underscore _ represents 1000 times).
37+
 Given a integer, convert it to an roman numeral.
38+
​    https://en.wikipedia.org/wiki/Roman_numerals
39+
>>> tests = {"III": 3, "CLIV": 154, "MIX": 1009, "MMD": 2500, "MMMCMXCIX": 3999, "I_V_": 4000, "X_": 10000, "M_": 1000000}
4640
>>> all(int_to_roman(value) == key for key, value in tests.items())
4741
True
4842
"""
43+
if not isinstance(number, int) or number < 1:
44+
raise ValueError("Input must be a positive integer greater than 0")
45+
4946
result = []
5047
for arabic, roman in ROMAN:
51-
(factor, number) = divmod(number, arabic)
48+
factor, number = divmod(number, arabic)
5249
result.append(roman * factor)
5350
if number == 0:
54-
break
51+
reak
5552
return "".join(result)
5653

57-
5854
if __name__ == "__main__":
5955
import doctest
60-
6156
doctest.testmod()

0 commit comments

Comments
 (0)