Skip to content

Instantly share code, notes, and snippets.

@jcalcutt
Last active April 23, 2021 17:06
Show Gist options
  • Save jcalcutt/1c147f818f7118d3d4f1d2666f517058 to your computer and use it in GitHub Desktop.
Save jcalcutt/1c147f818f7118d3d4f1d2666f517058 to your computer and use it in GitHub Desktop.
# numeral symbol mapping
symbols = {
1:"I",
5:"V",
10:"X",
50:"L",
100:"C",
500:"D",
1000:"M"
}
def numerals(n: int) -> str:
"""
Given an integer year from 1-3000, convert it to roman numerals
Parameters
----------
n : int
year to convert, valid from 1-3000, e.g. 1975
Returns
-------
str
Roman numeral representation of the requested year, e.g. MCMLXXV
Raises
------
ValueError
Year passed is too large
"""
result = []
sn = str(n)
x = len(str(n))
if n > 3000:
raise ValueError("Unable to handle year this large")
# milleniums
if x == 4:
# standalone logic to create the millenium numerals
result.extend(symbols[1000]*int(sn[-4]))
# check how many digits we have, and if we do, pass that digit to the numeral conversion logic
# centuries
if x >=3:
result.extend(numeral_logic(int(sn[-3]), symbols[100], symbols[500], symbols[1000]))
# decades
if x >=2:
result.extend(numeral_logic(int(sn[-2]), symbols[10], symbols[50], symbols[100]))
# years
if x >=1:
result.extend(numeral_logic(int(sn[-1]), symbols[1], symbols[5], symbols[10]))
# convert to string and return
return "".join(result)
def numeral_logic(value: int, small: str, mid: str, large: str) -> str:
"""
For a given number, and set of small, mid, and large numeral mappings, implement the roman numeral conversion logic.
Valid for centuries, decades and individual years.
Parameters
----------
value : int
century, decade, or year to convert to numeral
small : str
small unit for the value, e.g. "C" for a century value
mid : str
mid unit for the value, e.g. "D" for a century value
large : str
large unit for the value, e.g. "M" for a century value
Returns
-------
str
roman numeral representation for the requested value, e.g. "IV" for 4
"""
if value <= 3:
result = small*value
elif value == 4:
result = small + mid
elif value == 5:
result = mid
elif value > 5 and value <= 8:
n = value-5
result = mid + n*small
else:
# value = 9
result = small + large
return result
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment