Task

Create a function taking a positive integer as its parameter and returning a string containing the Roman numeral representation of that integer. Modern Roman numerals are written by expressing each digit separately, starting with the left most digit and skipping any digit with a value of zero.



In Roman numerals:

 1990 is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC
 2008 is written as 2000=MM, 8=VIII; or MMVIII
 1666 uses each Roman symbol in descending order: MDCLXVI


/* 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!=
*/