W naszym rozwoju cywilizacyjnym mieliśmy różne pomysły na zapisywanie liczb. Podczas zabawy z Pythonem postanowiłem zmierzyć się z jakimś realnym problemem, i padło na Liczby po rzymsku.
Zacznijmy od początku. Zasadniczo to wiedza szkolna ale dla przypomnienia. Do zapisywania liczb rzymianie używali symboli które zapisałem poniżej wraz z ich wartością:
I - 1 V - 5 X - 10 L - 50 C - 100 D - 500 M - 1000
Zasady zapisu liczb są proste:
1. Cyfry I, X, C, M mogą występować w maksymalnej ilości trzech identycznych koło siebie.
2. Cyfry V,L,D nie mogą sąsiadować.
3. Cyfry zapisujemy od lewej do prawej w porządku malejącym z wyjątkiem liczb: 9 (IX), 40 (XV), 400 (CD), 900 (CM).
Osoby spostrzegawcze wywnioskują że maksymalną wartość jaką można zapisać za pomocą tego systemu to 3999.
Zapiszmy teraz rok 1973 rozbijając go na tysiące, setki, dziesiątki i jednostki:
1000 - M 900 - CM 70 - LXX 3 - III
Po złożeniu dostajemy: MCMLXXIII
Prawda że proste?
To teraz ogarnijmy to programowo.
Najpierw zacznę od przygotowania tablic zawierających wartości jednostek, dziesiątek, setek i tysięcy.
roman_table_jedn = ["I","II","III","IV","V","VI","VII","VIII","IX"] roman_table_dzie = ["X","XX","XXX","XL","L","LX","LXX","LXXX","XC"] roman_table_setk = ["C","CC","CCC","CD","D","DC","DCC","DCCC","CM"] roman_table_tysi = ["M","MM","MMM"]
Następnie za pomocą dzielenia bez reszty wyciągam z liczby którą przetwarzam kolejne wartości.
input_int_tysi = (input_int / 1000) - 1 input_int_setk = ((input_int % 1000) / 100) -1 input_int_dzie = ((input_int % 100) / 10) -1 input_int_jedn = ((input_int % 100) % 10) - 1
Tak obliczamy wartość dla każdego rzędu wartości a następnie obniżamy ją o jeden, by wyciągnąć je z tablic. A w tablicach liczymy od zera.
Gotowa funkcja wygląda tak:
def to_roman(input_int=1): roman_table_jedn = ["I","II","III","IV","V","VI","VII","VIII","IX"] roman_table_dzie = ["X","XX","XXX","XL","L","LX","LXX","LXXX","XC"] roman_table_setk = ["C","CC","CCC","CD","D","DC","DCC","DCCC","CM"] roman_table_tysi = ["M","MM","MMM"] if(input_int < 1 or input_int > 3999): return else: input_int_tysi = (input_int / 1000) - 1 input_int_setk = ((input_int % 1000) / 100) -1 input_int_dzie = ((input_int % 100) / 10) -1 input_int_jedn = ((input_int % 100) % 10) - 1 return roman_table_tysi[input_int_tysi] + roman_table_setk[input_int_setk] + roman_table_dzie[input_int_dzie] + roman_table_jedn[input_int_jedn]
Tak przygotowana funkcja po wywołaniu zamienia wartości z zakresu od 1 do 3999 na zapis rzymski.
R.