Hace poco me hizo falta, para la realización de un proyecto educativo, tener la posibilidad de convertir de números arábigos a números romanos y viceversa, por lo que para lograrlo realicé una clase en ActionScript 3 que realiza esta tarea.
Aunque los números romanos ya están en desuso y es muy extraño que hoy en día alguien requiera utilizarlos he decidido compartir esta clase con la comunidad, quizás haya alguien que le sirva de ayuda la misma.
Esta clase asume que no se requerirá trabajar con números mayores de 3'999'999 por lo que cualquier valor que sobrepase esta cantidad arribará en un error de ejecución, para los números mayores de 3999 se utilizó la notación de entre paréntesis para indicar que la base de multiplicación es 1000.
Aquí tienen el contenido de la clase ubicada en el package ecn.format
Código :
package ecn.format { public class RomanNumbers { protected static const _letters:Array = ["I", "V", "X", "L", "C", "D", "M", "(V)", "(X)", "(L)", "(C)", "(D)", "(M)"]; protected static const _regexp:RegExp = /^((\(M\)){0,3})(\(C\)\(M\)|\(C\)\(D\)|(\(D\))?(\(C\)){0,3})(\(X\)\(C\)|\(X\)\(L\)|(\(L\))?(\(X\)){0,3})(M\(X\)|M\(V\)|(\(V\))?)(M{0,3})(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/; //---Método de hacer un test del número romano public static function testRoman(roman:String):Boolean { return _regexp.test(roman); } //---Método de obtener un número romano public static function getRomanNumber(number:uint):String { if (number > 3999999) trace(new Error("Numbers higher than 3999999 can't be converted to Roman. Try lower value!")); var roman:String = ""; var cant:uint = String(number).length; var narray:Array = String(number).split("").reverse(); var parser:Function = function(item:String, index:int, a:Array):void { switch (item) { case "0": case "1": case "2": case "3": roman = repeat(_letters[index * 2], uint(item)) + roman; break; case "4": roman = (_letters[index * 2] + _letters[index * 2 + 1]) + roman; break; case "5": case "6": case "7": case "8": roman = _letters[index * 2 + 1] + repeat(_letters[index * 2], uint(item) - 5) + roman; break; case "9": roman = _letters[index * 2] + _letters[index * 2 + 2] + roman; break; } } narray.forEach(parser); return roman; } //---Método de obtener el número arábigo public static function getArabicNumber(roman:String):uint { if (!testRoman(roman)) trace(new Error("You enter an invalid roman number. Please try with another value")); var reg:RegExp = /(\()(\w)(\))/g; var simple:String; var values:uint = 0; var array:Array = _regexp.exec(roman); array.splice(0, 1); array.splice(1, 1); array.splice(2, 2); array.splice(3, 2); array.splice(4, 1); var parser:Function = function(item:String, index:int, a:Array):void { switch(index){ case 0: case 1: case 2: simple = item.replace(reg, "$2"); values += getValue(simple) * 1000; break; case 3: simple = item.replace(reg, "$2"); values += ((simple.slice(0, 1) == "M") ? getValue(simple.slice(1, 2)) * 1000 - getValue(simple.slice(0, 1)) : getValue(simple) * 1000); break; case 4: case 5: case 6: case 7: values += getValue(item); break; } } array.forEach(parser); return values; } //---Función de devolver un número a partir de un string romano protected static function getValue(str:String):uint { var cant:uint = str.length; var chars:Array; var ret:uint; switch(cant) { case 1: ret = getNumberByIndex(_letters.indexOf(str)); break; case 2: chars = str.split(""); ret = ((_letters.indexOf(chars[0]) < _letters.indexOf(chars[1])) ? getNumberByIndex(_letters.indexOf(chars[1])) - getNumberByIndex(_letters.indexOf(chars[0])) : getNumberByIndex(_letters.indexOf(chars[0])) + getNumberByIndex(_letters.indexOf(chars[1]))); break; case 3: chars = str.split(""); ret = sumAllNumbers(getNumberByIndex(_letters.indexOf(chars[0])), getNumberByIndex(_letters.indexOf(chars[1])), getNumberByIndex(_letters.indexOf(chars[2]))); break; case 4: chars = str.split(""); ret = sumAllNumbers(getNumberByIndex(_letters.indexOf(chars[0])), getNumberByIndex(_letters.indexOf(chars[1])), getNumberByIndex(_letters.indexOf(chars[2])), getNumberByIndex(_letters.indexOf(chars[3]))); break; } return ret; } //---Retornar un número de acuerdo a su index en el arreglo de letras protected static function getNumberByIndex(index:uint):uint { return ((index % 2 == 0) ? Math.pow(10, index / 2) : Math.pow(10, (index + 1) / 2) / 2); } //---Función de devolver un string repetido protected static function repeat(char:String, times:uint):String { var ret:String = ""; while (times > 0) { ret += char; times--; } return ret; } //---Función de sumar varios números protected static function sumAllNumbers(...rest):uint { var all:uint = 0; var n:uint; for each(n in rest) { all += n; } return all; } } }
La clase cuenta con tres métodos estáticos:
testRoman
public static function testRoman(roman:String):BooleanComprueba si el valor enviado es un número romano válido
Parámetros
roman:String Valor de tipo cadena con la representación del número romanoDevuelve
BooleangetRomanNumber
public static function getRomanNumber(number:uint):StringDevuelve un número romano
Parámetros
number:uint Valor positivo entero mayor que 0 con el número que se desea convertirDevuelve
String Representación del número romanogetArabicNumber
public static function getArabicNumber(roman:String):uintDevuelve un número arábigo
Parámetros
roman:String Valor de tipo cadena con la representación del número romanoDevuelve
uint Valor entero positivo con la representación numérica del número arábigoEjemplos
Código :
import ecn.format.RomanNumbers; trace(RomanNumbers.testRoman("MMX")); //true trace(RomanNumbers.testRoman("XMM")); //false trace(RomanNumbers.getRomanNumber(123456)); //(C)(X)(X)MMMCDLVI trace(RomanNumbers.getArabicNumber("(D)(C)(L)M(V)CCCXXI")); //654321
Aquí les dejo una pequeña aplicación con la implementación de la clase:
Espero que les sea de ayuda.
Un saludo
¿Sabes SQL? ¿No-SQL? Aprende MySQL, PostgreSQL, MongoDB, Redis y más con el Curso Profesional de Bases de Datos que empieza el martes, en vivo.
Por Zguillez el 03 de Febrero de 2010
Por The Fricky! el 03 de Febrero de 2010
Por paty el 05 de Marzo de 2010
Por alberto el 06 de Marzo de 2010
Por airfruxdgygftfbh0oyb el 06 de Marzo de 2010
d
d
fcvbgiixfdr8
Por debora el 17 de Marzo de 2010
Por elchininet el 18 de Marzo de 2010
debora-blog :
Freddie el FBI ya te debe andar buscando
Por nahuel el 07 de Mayo de 2010
Por Dios Otaku el 29 de Septiembre de 2010
si lo se se la fumo
pero trabajo es trabajo muchisimas gracias
Por Dios Otaku el 29 de Septiembre de 2010
Por elchininet el 29 de Septiembre de 2010
Código :