#! user/bin/env python
# -*- encoding: utf-8 -*-
numeracion = {"I": 1, "IV": 4, "V": 5, "X": 10, "XL": 40, "L": 50, "XC": 90, "C": 100, "CD": 400, "D": 500, "CM": 900}
unidades = ["I", "IV", "V", "IX"]
decenas = ["X", "XL", "L", "XC"]
centenas = ["C", "CD", "D", "CM"]
class numero_a_Romano(object):
def __init__(self, num=0):
self.num = num
self.out = None
if num > 0:
self.setNum(num)
else:
self.num = 0
def __str__(self):
return self.out
def __add__(self, other):
return numero_a_Romano(self.num + other.num)
def __sub__(self, other):
return numero_a_Romano(self.num - other.num)
def transform(self, num, out):
if num == 9:
self.out = "{0}{1}".format(self.out, out[3])
num = 0
elif num >= 5:
self.out = "{0}{1}".format(self.out, out[2])
num -= 5
elif num == 4:
self.out = "{0}{1}".format(self.out, out[1])
num = 0
if num > 0:
self.out = "{0}{1}".format(self.out, out[0] * num)
def conversor(self):
aux = 1
digitos = -1
while aux <= self.num:
digitos += 1
aux *= 10
if digitos < 3:
num = self.num
for i in range(0, digitos + 1):
posN = 10 ** (digitos - i)
aux = int(num / posN)
if posN == 1:
self.transform(aux, unidades)
elif posN == 10:
self.transform(aux, decenas)
elif posN == 100:
self.transform(aux, centenas)
num %= posN
else:
self.out = None
def setNum(self, num):
self.num = num
self.out = ""
self.conversor()
def getNum(self):
return self.out
class romano_a_numero(object):
def __init__(self, num=""):
self.num = num.upper()
self.out = 0
if(self.num != ""):
self.conversor()
def __str__(self):
return str(self.out)
def busqueda(self, key):
try:
r = numeracion[key]
return r > 0
except KeyError:
return False
def conversor(self):
aux = self.num
l = len(aux)-1
i = 0
while i < l:
key = "{0}{1}".format(aux[i], aux[i+1])
if self.busqueda(key):
self.out += numeracion[key]
i += 1
else:
self.out += numeracion[aux[i]]
i += 1
self.out += numeracion[aux[i]]
r = numero_a_Romano(943)
r2 = romano_a_numero(r.getNum())
print(r)
print(r2)
IyEgdXNlci9iaW4vZW52IHB5dGhvbgojIC0qLSBlbmNvZGluZzogdXRmLTggLSotCgpudW1lcmFjaW9uID0geyJJIjogMSwgIklWIjogNCwgIlYiOiA1LCAiWCI6IDEwLCAiWEwiOiA0MCwgIkwiOiA1MCwgIlhDIjogOTAsICJDIjogMTAwLCAiQ0QiOiA0MDAsICJEIjogNTAwLCAiQ00iOiA5MDB9CnVuaWRhZGVzID0gWyJJIiwgIklWIiwgIlYiLCAiSVgiXQpkZWNlbmFzID0gIFsiWCIsICJYTCIsICJMIiwgIlhDIl0KY2VudGVuYXMgPSBbIkMiLCAiQ0QiLCAiRCIsICJDTSJdCgoKY2xhc3MgbnVtZXJvX2FfUm9tYW5vKG9iamVjdCk6CiAgICBkZWYgX19pbml0X18oc2VsZiwgbnVtPTApOgogICAgICAgIHNlbGYubnVtID0gbnVtCiAgICAgICAgc2VsZi5vdXQgPSBOb25lCiAgICAgICAgaWYgbnVtID4gMDoKICAgICAgICAgICAgc2VsZi5zZXROdW0obnVtKQogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYubnVtID0gMAoKICAgIGRlZiBfX3N0cl9fKHNlbGYpOgogICAgICAgIHJldHVybiBzZWxmLm91dAoKICAgIGRlZiBfX2FkZF9fKHNlbGYsIG90aGVyKToKICAgICAgICByZXR1cm4gbnVtZXJvX2FfUm9tYW5vKHNlbGYubnVtICsgb3RoZXIubnVtKQoKICAgIGRlZiBfX3N1Yl9fKHNlbGYsIG90aGVyKToKICAgICAgICByZXR1cm4gbnVtZXJvX2FfUm9tYW5vKHNlbGYubnVtIC0gb3RoZXIubnVtKQoKICAgIGRlZiB0cmFuc2Zvcm0oc2VsZiwgbnVtLCBvdXQpOgogICAgICAgIGlmIG51bSA9PSA5OgogICAgICAgICAgICBzZWxmLm91dCA9ICJ7MH17MX0iLmZvcm1hdChzZWxmLm91dCwgb3V0WzNdKQogICAgICAgICAgICBudW0gPSAwCiAgICAgICAgZWxpZiBudW0gPj0gNToKICAgICAgICAgICAgc2VsZi5vdXQgPSAiezB9ezF9Ii5mb3JtYXQoc2VsZi5vdXQsIG91dFsyXSkKICAgICAgICAgICAgbnVtIC09IDUKICAgICAgICBlbGlmIG51bSA9PSA0OgogICAgICAgICAgICBzZWxmLm91dCA9ICJ7MH17MX0iLmZvcm1hdChzZWxmLm91dCwgb3V0WzFdKQogICAgICAgICAgICBudW0gPSAwCiAgICAgICAgaWYgbnVtID4gMDoKICAgICAgICAgICAgc2VsZi5vdXQgPSAiezB9ezF9Ii5mb3JtYXQoc2VsZi5vdXQsIG91dFswXSAqIG51bSkKCiAgICBkZWYgY29udmVyc29yKHNlbGYpOgogICAgICAgIGF1eCA9IDEKICAgICAgICBkaWdpdG9zID0gLTEKCiAgICAgICAgd2hpbGUgYXV4IDw9IHNlbGYubnVtOgogICAgICAgICAgICBkaWdpdG9zICs9IDEKICAgICAgICAgICAgYXV4ICo9IDEwCgogICAgICAgIGlmIGRpZ2l0b3MgPCAzOgogICAgICAgICAgICBudW0gPSBzZWxmLm51bQogICAgICAgICAgICBmb3IgaSBpbiByYW5nZSgwLCBkaWdpdG9zICsgMSk6CiAgICAgICAgICAgICAgICBwb3NOID0gMTAgKiogKGRpZ2l0b3MgLSBpKQogICAgICAgICAgICAgICAgYXV4ID0gaW50KG51bSAvIHBvc04pCiAgICAgICAgICAgICAgICBpZiBwb3NOID09IDE6CiAgICAgICAgICAgICAgICAgICAgc2VsZi50cmFuc2Zvcm0oYXV4LCB1bmlkYWRlcykKICAgICAgICAgICAgICAgIGVsaWYgcG9zTiA9PSAxMDoKICAgICAgICAgICAgICAgICAgICBzZWxmLnRyYW5zZm9ybShhdXgsIGRlY2VuYXMpCiAgICAgICAgICAgICAgICBlbGlmIHBvc04gPT0gMTAwOgogICAgICAgICAgICAgICAgICAgIHNlbGYudHJhbnNmb3JtKGF1eCwgY2VudGVuYXMpCiAgICAgICAgICAgICAgICBudW0gJT0gcG9zTgogICAgICAgIGVsc2U6CiAgICAgICAgICAgIHNlbGYub3V0ID0gTm9uZQoKICAgIGRlZiBzZXROdW0oc2VsZiwgbnVtKToKICAgICAgICBzZWxmLm51bSA9IG51bQogICAgICAgIHNlbGYub3V0ID0gIiIKICAgICAgICBzZWxmLmNvbnZlcnNvcigpCgogICAgZGVmIGdldE51bShzZWxmKToKICAgICAgICByZXR1cm4gc2VsZi5vdXQKCgpjbGFzcyByb21hbm9fYV9udW1lcm8ob2JqZWN0KToKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBudW09IiIpOgogICAgICAgIHNlbGYubnVtID0gbnVtLnVwcGVyKCkKICAgICAgICBzZWxmLm91dCA9IDAKCiAgICAgICAgaWYoc2VsZi5udW0gIT0gIiIpOgogICAgICAgICAgICBzZWxmLmNvbnZlcnNvcigpCgogICAgZGVmIF9fc3RyX18oc2VsZik6CiAgICAgICAgcmV0dXJuIHN0cihzZWxmLm91dCkKCiAgICBkZWYgYnVzcXVlZGEoc2VsZiwga2V5KToKICAgICAgICB0cnk6CiAgICAgICAgICAgIHIgPSBudW1lcmFjaW9uW2tleV0KICAgICAgICAgICAgcmV0dXJuIHIgPiAwCiAgICAgICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgICAgICByZXR1cm4gRmFsc2UKCiAgICBkZWYgY29udmVyc29yKHNlbGYpOgogICAgICAgIGF1eCA9IHNlbGYubnVtCiAgICAgICAgbCA9IGxlbihhdXgpLTEKICAgICAgICBpID0gMAoKICAgICAgICB3aGlsZSBpIDwgbDoKICAgICAgICAgICAga2V5ID0gInswfXsxfSIuZm9ybWF0KGF1eFtpXSwgYXV4W2krMV0pCiAgICAgICAgICAgIGlmIHNlbGYuYnVzcXVlZGEoa2V5KToKICAgICAgICAgICAgICAgIHNlbGYub3V0ICs9IG51bWVyYWNpb25ba2V5XQogICAgICAgICAgICAgICAgaSArPSAxCiAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICBzZWxmLm91dCArPSBudW1lcmFjaW9uW2F1eFtpXV0KICAgICAgICAgICAgaSArPSAxCiAgICAgICAgc2VsZi5vdXQgKz0gbnVtZXJhY2lvblthdXhbaV1dCgoKCgpyID0gbnVtZXJvX2FfUm9tYW5vKDk0MykKcjIgPSByb21hbm9fYV9udW1lcm8oci5nZXROdW0oKSkKCnByaW50KHIpCnByaW50KHIyKQ==