Enable Javascript in your browser and then refresh this page, for a much enhanced experience.
reminder subtraction solution in Clear category for Roman Numerals by GlulkAlex
def checkio(data):
"""
collections.namedtuple(typename, field_names, *, verbose=False, rename=False, module=None)
subtractive notation for more then 3 * Numeral
Number : 4 9 40 90 400 900
Notation: IV IX XL XC CD CM
"""
from collections import namedtuple
from pprint import pprint, pformat
#
#
# replace this for solution
is_DeBug_Mode = 1 == 0
# case Class|record
Num_Val = namedtuple( "Num_Val", [ "val", "txt" ] )
roman_Numeral = ""
roman_Numerals_To_Dec_Map = {
#Numeral Value (description)
'I': Num_Val( 1, "unus" ),
'V': Num_Val( 5, "quinque" ),
'X': Num_Val( 10, "decem" ),
'L': Num_Val( 50, "quinquaginta" ),
'C': Num_Val( 100, "centum" ),
'D': Num_Val( 500, "quingenti" ),
'M': Num_Val( 1000, "mille" )
}
dec_To_Roman_Numerals_Map = {
#Numeral Value (description)
1: Num_Val( 'I', "unus" ),
5: Num_Val( 'V', "quinque" ),
10: Num_Val( 'X', "decem" ),
50: Num_Val( 'L', "quinquaginta" ),
100: Num_Val( 'C', "centum" ),
500: Num_Val( 'D', "quingenti" ),
1000: Num_Val( 'M', "mille" )
}
nominals_Sorted = sorted( dec_To_Roman_Numerals_Map.keys(), reverse = True )
subtractions_Map = {
#Number : Notation
# (-1)
4: Num_Val( "IV", "5-1" ),
9: Num_Val( "IX", "10-1" ),
# (-10)
40: Num_Val( "XL", "50-10" ),
90: Num_Val( "XC", "100-10" ),
# (-100)
400: Num_Val( "CD", "500-100" ),
900: Num_Val( "CM", "1000-100" )
}
subtractions_Sorted = sorted( subtractions_Map.keys(), reverse = True )
#print( "data:{}".format( data ) )
#pprint( roman_Numerals_To_Dec_Map )
#pprint( dec_To_Roman_Numerals_Map )
#pprint( nominals_Sorted )
reminder = data
while reminder > 0:
for ( n_i, nominal ) in enumerate( nominals_Sorted ):
# @toDo: it must handle (99) as 'XCIX':(100 - 10)+(10-1)
if nominal <= reminder:
diff = reminder - nominal
if is_DeBug_Mode:
print(
"nominal:{} <= {}:reminder, diff:{}".format(
nominal, reminder, diff ) )
if nominal * 4 <= reminder and n_i > 0:
if 1 == 0:
times = 4
roman_Numeral += dec_To_Roman_Numerals_Map[
nominal ].val#[ 0 ]
roman_Numeral += dec_To_Roman_Numerals_Map[
nominals_Sorted[ n_i - 1 ] ].val
reminder -= times * nominal
for subtraction in subtractions_Sorted:
if subtraction <= reminder:
diff = reminder - subtraction
numeral = subtractions_Map[ subtraction ].val#[ 0 ]
roman_Numeral += numeral
print(
"subtraction:{} <= {}:reminder, \
diff:{}, numeral:{}".format(
subtraction, reminder, diff, numeral ) )
reminder -= subtraction
break #for
else:
times = reminder // nominal
numeral = dec_To_Roman_Numerals_Map[ nominal ].val#[ 0 ]
roman_Numeral += times * numeral
if is_DeBug_Mode:
print(
"times:{} * numeral:{} == '{}'".format(
times, numeral, times * numeral ) )
reminder -= times * nominal
#
break #for
else:#if nominal > reminder:
# 100 - 10 = 90, dif:10 == 10
# 100 vs. 99 diff: 1 < 10
# 100 vs. 89 diff: 11 > 10
# 100 - 50 = 50, dif:50 == 50 <- but not subtractable
# 50 - 10 = 40, dif:10 == 10
# 10 - 1 = 9, dif:1 == 1
# 10 - 5 = 5, dif:5 == 5 <- but not subtractable
# 5 - 1 = 4, dif:1 == 1
diff = nominal - reminder
if is_DeBug_Mode:
print(
"nominal:{} > {}:reminder, diff:{}".format(
nominal, reminder, diff ) )
for subtraction in [ 100, 10, 1 ]:
if reminder > subtraction and diff <= subtraction:
if is_DeBug_Mode:
print( "subtraction:{}".format( subtraction ) )
diff = nominal - subtraction
numeral = subtractions_Map[ diff ].val#[ 0 ]
roman_Numeral += numeral
if is_DeBug_Mode:
print(
"subtraction:{} <= {}:reminder, diff:{}, numeral:{}".format(
subtraction, reminder, diff, numeral ) )
reminder -= diff
break #for
#
if is_DeBug_Mode:
print( "data:{} == {}".format( data, roman_Numeral ) )
#
return roman_Numeral#""
#
if __name__ == '__main__':
#These "asserts" using only for self-checking and not necessary for auto-testing
assert checkio(6) == 'VI', '6'
assert checkio(76) == 'LXXVI', '76'
assert checkio(499) == 'CDXCIX', '499'
assert checkio(3888) == 'MMMDCCCLXXXVIII', '3888'
July 31, 2017