Numerais Romanos

Conversor de Numerais Romanos bi-direcional em JavaScript e Python.

Código fonte em HTML + JavaScript

<!DOCTYPE html><html><head>
  <meta charset="utf-8">
  <title>Conversor de Numerais Romanos</title>
  <style>
    body { 
      font-family: "Arial", Sans-Serif;
      font-size: 12pt;
    }
  </style>
</head>
<body><h2>Conversor de Numerais Romanos</h2>
  <ul>
    <li>Numerais romanos representam posicionalmente valores de 1 a 3999</li>
    <li>O uso de parênteses para representar milhar não é convencional</li>
    <li>O número romano mais longo tem 15 caracteres (3888)</li>
    <li>Não existe símbolo para zero</li>
  </ul>
  <!-- Interface HTML, campos de entrada e saída de dados -->
  <table><tr><td>
    <label for="roman">Numeral Romano:</label><br>
    <label for="arabic">Numeral Arábico:</label></td><td>
    <input type="text" id="roman" name="roman" oninput="r2a()"><br>
    <input type="number" id="arabic" name="arabic"  oninput="a2r()">
  </td></tr></table>
  <!-- JS funções chamadas ao mudar os dados nos campos acima -->
  <script>
    function r2a() {
      map = {'I': 1, 'V': 5, 'X': 10, 'L': 50, 'C': 100, 'D': 500, 'M': 1000};
      s = get("roman").toUpperCase().replaceAll(' ', ''); // --> maiúsculas, remove espaços
      put("arabic", [...s].reduce((r,c,i,s) => map[s[i+1]] > map[c] ? r-map[c] : r+map[c], 0));
    }
    function a2r() {
      s = "M1000CM900D500CD400C100XC90L50XL40X10IX9V5IV4I1";
      f=n=>n<4e3?s.replace(/(\D+)(\d+)/g,(_,r,d)=>r.repeat(n/d,n%=d)):`(${f(n/1e3)})`+f(n%1e3);
      put("roman", f(get("arabic")));
    }
    function get(i) { // lê dado do campo i (input)
      return document.getElementById(i).value;
    }
    function put(o,v) { // grava dado no campo o (output)
      document.getElementById(o).value=v;
    }
  </script>
</body></html>

Código fonte em python

romanConvert.py

# roman numerals convertion library by Rogério Neves

c="M CM D CD C XC L XL X IX V IV I".split()   # Code/symbol
v=[1000,900,500,400,100,90,50,40,10,9,5,4,1]  # Value

def a2r(A,R=''):
    ''' Convert Arabic to Roman numerals'''
    for x,y in zip(c,v):
        if n:=A//y:R+=x*n;A%=n*y
    return R

def r2a(R):
    ''' Convert Roman to Arabic numerals'''
    A,x,R=0,0,R.upper()
    while x<len(R):
        if R[x:x+2] in c:
            A+=v[c.index(R[x:x+2])]
            x+=1
        elif R[x:x+1] in c:
            A+=v[c.index(R[x:x+1])]
        x+=1
    return A

def test():
    ''' Test cases '''
    help(r2a)
    help(a2r)
    print("r2a('MMMCMXCIX')) --> ", r2a('MMMCMXCIX'))
    print('a2r(3999) -->', a2r(3999))
    print("r2a('CDXLIV') --> ", r2a('CDXLIV'))
    print('a2r(444) -->', a2r(444))
    print('a2r(3888) -->', a2r(3888))
    print("r2a('MMMDCCCLXXXVIII') --> ", r2a('MMMDCCCLXXXVIII'))
    for i in range(4000):
        if len(a2r(i))>13:
            print(f"({len(a2r(i))}) {a2r(i)} = {i}")

if __name__ == "__main__":
    test()

Saída (test block)

Uso como biblioteca

import romanConvert as rc

help(rc)

print(f'{rc.r2a('MMMCMXCIX') = }')
print(f'{rc.a2r(494) = }')
from romanConvert import a2r

longRomanNumber = a2r(3888)

Ref.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *