Rzymski system zapisywania liczb

By | Grudzień 4, 2020

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.