/* Roman numerals, in Jsish */ var Roman = { ord: ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'], val: [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1], fromRoman: function(roman:string):number { var n = 0; var re = /IV|IX|I|V|XC|XL|X|L|CD|CM|C|D|M/g; var matches = roman.match(re); if (!matches) return NaN; for (var hit of matches) n += this.val[this.ord.indexOf(hit)]; return n; }, toRoman: function(n:number):string { var roman = ''; var idx = 0; while (n > 0) { while (n >= this.val[idx]) { roman += this.ord[idx]; n -= this.val[idx]; } idx++; } return roman; } }; provide('Roman', 1); if (Interp.conf('unitTest')) { ; Roman.fromRoman('VIII'); ; Roman.fromRoman('MMMDIV'); ; Roman.fromRoman('CDIV'); ; Roman.fromRoman('MDCLXVI'); ; Roman.fromRoman('not'); ; Roman.toRoman(8); ; Roman.toRoman(3504); ; Roman.toRoman(404); ; Roman.toRoman(1666); } /* =!EXPECTSTART!= Roman.fromRoman('VIII') ==> 8 Roman.fromRoman('MMMDIV') ==> 3504 Roman.fromRoman('CDIV') ==> 404 Roman.fromRoman('MDCLXVI') ==> 1666 Roman.fromRoman('not') ==> NaN Roman.toRoman(8) ==> VIII Roman.toRoman(3504) ==> MMMDIV Roman.toRoman(404) ==> CDIV Roman.toRoman(1666) ==> MDCLXVI =!EXPECTEND!= */