View Full Version : A New (better) Challenge
beetle
01-03-2003, 05:57 AM
Ok, now that I have some peace and quiet at my house, and I've learned what to and not to do from my last challenge, here's something new for you folks, and much more challenging.
The Challenge
Create a function OR method for converting a roman numeral string into a base-10 integer.
The Rules No JScript-only functions or methods, must be ECMAscript compliant
Shorthand (ternarys, multiple assignment, literals, etc are allowed)
nested functions are allowed. Function declaration will NOT be counted as a separate line, since function blah() { //code } is technically valid
Function must be completely independent (not rely on any classes or libraries you may have already written)
Function should NOT assume the this numeral has been entered in the proper case
Function must return some identifiable value if string passed is not a valid roman numeral such as 'NaN' or NULL
Use HTML shell(s) provided below and only change areas marked.
Code will be tested with IE6 and Mozilla 1.1
Submit by 12:00 pm CST Jan 04, 2003Grading
Will be decided on a case-by-case basis
Disqualifications Your submission has ANY errors, including minor grammatical or spelling
Code does not work with 100% of test data (provided below)
You've already seen Aaron Broodman's version at youngpup.net (honor system here, please)
Multiple entries. Make sure your done before you post!
Submissions made after the deadlineTest Data MMMMMMMMMMMMCCCXLV -> 12345
MCMLXXVIII -> 1978
CMXCIX -> 999
MCDXCII -> 1492
MCXI -> 1111
MMIII -> 2003
MMMCMXXXIX -> 3939
MDCCLXXVI -> 1776
LXIV -> 64
DLV -> 555
VC -> Invalid
MCVIX -> InvalidShell - if making a function<html>
<head>
<title>Roman Numeral converter</title>
<script type="text/javascript">
function rn2dec(str)
{
// code here
}
</script>
</head>
<body>
<form>
<input type="text" name="text1" size="80" />
<br />
<input type="button" value="convert" onclick="this.form.text1.value = rn2dec(this.form.text1.value)" />
</form>
</body>
</html>Shell - if making a method<html>
<head>
<title>Roman Numeral converter</title>
<script type="text/javascript">
String.prototype.rn2dec = function()
{
// code here
}
</script>
</head>
<body>
<form>
<input type="text" name="text1" size="80" />
<br />
<input type="button" value="convert" onclick="this.form.text1.value = this.form.text1.value.rn2dec();" />
</form>
</body>
</html>Good Luck!
Roelf
01-03-2003, 10:35 AM
<html>
<head>
<title>Roman Numeral converter</title>
<script type="text/javascript">
function rn2dec(str)
{
var M=1000; D=500; C=100; L=50; X=10; V=5;I=1;previousdigit=0;val=0;correct="MDCLXVI";
for (var i = 0; i <= str.length; i++) {
(i<str.length)?((correct.indexOf(str.charAt(i).toUpperCase())>-1)?(digit=eval(str.charAt(i).toUpperCase())):(digit=NaN)):(digit=0);
(digit > previousdigit)? (val -= previousdigit) : (val += previousdigit);
previousdigit = digit;
}
return (val);
}
</script>
</head>
<body>
<form>
<input type="text" name="text1" size="80" />
<br />
<input type="button" value="convert" onclick="this.form.text1.value = rn2dec(this.form.text1.value)" />
</form>
</body>
</html>
Algorithm
01-03-2003, 10:47 AM
function rn2dec(str){
for(var a=str.toUpperCase().split(''),
i=(a.length-1),
c='0';
i>=0;
a[i]=(a[i]=='I')?'1':(a[i]=='V')?'5':(a[i]=='X')?'10':(a[i]=='L')?
'50':(a[i]=='C')?'100':(a[i]=='D')?'500':(a[i]=='M')?'1000':'NaN',
a[i]=(eval(c+'>'+a[i])?'-':'+')+a[i],
c=a[i],
i--);
return eval('0'+a.join(''));
}
santigoon
01-03-2003, 11:44 AM
function rn2dec(str)
{
return p=v=0, str.toUpperCase().replace( /./g, function(a){ q=p,p={M:1e3, D:5e2, C:1e2, L:50, X:10, V:5, I:1}[a], v+=(p>q)?p-q-q:p;}), v;
};
This has one flaw. An invalid rn like IVC is still recognized as a number. A fix would be to modify the literal as it parses. So when IV is recognized, the literal (let's call it m) is modified with m.M=m.D=m.C=m.L=null. Any non valid characters will result in a NaN after that. This would result in a much larger code segment, although it could be reduced by using m[0] in stead of m.M. Since the last one might not be emac-262 it's a trade off.
santigoon
01-03-2003, 11:46 AM
That last smiley should of course be :p (: p)
Did not see the checkbox below.
mordred
01-03-2003, 01:41 PM
I want to win in the readability category:
String.prototype.rn2dec = function()
{
// check for valid chars and minimum 1 char
if ( this.length < 1 || this.match(/[^IVXLCDM]|I{4,}|V{4,}|X{4,}|L{4,}|C{4,}|D{4,}/i) ) {
return Number.NaN;
}
// split the string into an array
var data = this.toUpperCase().split('');
// conversion factors as an object
var factors = {
'I' : 1, 'V' : 5, 'X' : 10, L : 50,
'C' : 100, 'D' : 500, 'M' : 1000
};
// temporary result storage variables
var temp, result = 0;
for (var i = 0; i < data.length; i++) {
temp = factors[data[i]];
// increase temporary variable for each same char found
while (i+1 < data.length && data[i] == data[i+1]) {
temp += factors[data[i]];
i++;
}
if (factors[data[i+1]] > factors[data[i]]) {
// invalid roman number - more than two "lower" chars
// before one "higher" char is found
if (i-1 >= 0 && data[i] == data[i-1] ) {
return Number.NaN;
}
// subtract nearest "lower" char form "higher" char
result += temp + factors[data[i+1]] - 2 * (factors[data[i]]);
i++;
} else {
// increase result variable
result += temp;
}
// reset temporary variable to zero
temp = 0;
}
return result;
}
this is fun... :)
Vladdy
01-03-2003, 01:46 PM
Ok, then...
I want to win in the "compromise between short and readable" category :D :D
<html>
<head>
<title>Roman Numeral converter</title>
<script type="text/javascript">
function rn2dec(str)
{ vr=/^\s*m{0,3}(?:cm|cd|d)?c{0,3}(?:xc|xl|l)?x{0,3}(?:ix|iv|v)?i{0,3}\s*$/i;
if(!vr.test(str)) return NaN;
r=[/cm/ig,/cd/ig,/xc/ig,/xl/ig,/ix/ig,/iv/ig,/m/ig,/d/ig,/c/ig,/l/ig,/x/ig,/v/ig,/i/ig];
d=['900 ','400 ','90 ','40 ','9 ','4 ','1000 ','500 ','100 ','50 ','10 ','5 ','1 '];
for(i=0;i<13;i++) str=str.replace(r[i],d[i]);
a=str.replace(/\s+$/,"").replace(/^\s+/,"").split(' ');
for(i=0,n=0;i<a.length;i++) n+=parseInt(a[i]);
return n;
}
</script>
</head>
<body>
<form>
<input type="text" name="text1" size="80" />
<br />
<input type="button" value="convert" onclick="this.form.text1.value = rn2dec(this.form.text1.value)" />
</form>
</body>
</html>
Suggestion:
The winner has to come up with the next challenge
beetle
01-03-2003, 03:05 PM
Well, so far I am both impressed, and dissapointed. There is some great code here, but all five current submissions don't follow one of my rules. Function must return some identifiable value if string passed is not a valid roman numeral such as 'NaN' or NULLNow, normally, this would result in each of you being disqualified, however, since this challenge thing is still new, I'll allow each of you to change your code to accomodate this rule. Each of you seems to know the rules for roman numeral conversion, but if you are unsure of what makes a roman numeral invalid, let me know. I have added new test data in my top post.
Please, modify your existing posts and PM me when you have done so.
santigoon
01-03-2003, 03:34 PM
Beetle, Vladdy, Mordred's function and mine all return NaN in case of an invalid entry.
Mordred has an explicit return for a mismatched text.
Vladdy uses parseInt, which returns the required NaN.
Mine is implied by adding an undefined value to a 0, which has the same effect.
I didn't check the ones before that though.
For readability I vote for mordred. There is slight flaw in it however. If i=data.length after the first loop, the tempvalue addition (undefined>x resolves to false) might introduce an error.
beetle
01-03-2003, 03:52 PM
Sorry, santigoon. I disagree.
Yes, each of those return NaN of anything but valid roman numeral characters are entered, but not if an actual invalid roman numeral is entered. The examples below plus the two pieces of test data I added are all invalid roman numerals, even though they are constructed from valid roman numeral characters
improper -> dec -> proper
XXXX -> 40 -> XL
IC -> 99 -> XCIX
VIX -> 14 -> XIV
Also, allow me to borrow some text from this page (http://diveintopython.org/roman_divein.html)
There are some general rules for constructing Roman numerals: Characters are additive. I is 1, II is 2, and III is 3. VI is 6 (literally, "5 and 1"), VII is 7, and VIII is 8.
The tens characters (I, X, C, and M) can be repeated up to three times. At 4, you have to subtract from the next highest fives character. You can’t represent 4 as IIII; instead, it is represented as IV ("1 less than 5"). 40 is written as XL ("10 less than 50"), 41 as XLI, 42 as XLII, 43 as XLIII, and then 44 as XLIV ("10 less than 50, then 1 less than 5").
Similarly, at 9, you have to subtract from the next highest tens character: 8 is VIII, but 9 is IX ("1 less than 10"), not VIIII (since the I character can not be repeated four times). 90 is XC, 900 is CM.
The fives characters can not be repeated. 10 is always represented as X, never as VV. 100 is always C, never LL.
Roman numerals are always written highest to lowest, and read left to right, so order of characters matters very much. DC is 600; CD is a completely different number (400, "100 less than 500"). CI is 101; IC is not even a valid Roman numeral (because you can’t subtract 1 directly from 100; you would have to write it as XCIX, "10 less than 100, then 1 less than 10").These rules lead to a number of interesting observations: There is only one correct way to represent a number as Roman numerals.
The converse is also true: if a string of characters is a valid Roman numeral, it represents only one number (i.e. it can only be read one way).
There is a limited range of numbers that can be expressed as Roman numerals, specifically 1 through 3999. (The Romans did have several ways of expressing larger numbers, for instance by having a bar over a numeral to represent that its normal value should be multiplied by 1000, but we’re not going to deal with that. For the purposes of this chapter, Roman numerals go from 1 to 3999.)
There is no way to represent 0 in Roman numerals. (Amazingly, the ancient Romans had no concept of 0 as a number. Numbers were for counting things you had; how can you count what you don’t have?)
There is no way to represent negative numbers in Roman numerals.
There is no way to represent decimals or fractions in Roman numerals.Note: Yes, I recognize that my first piece of test data is out of the range defined here. I just wanted to see what it took to make 12345 ;) If your converter doesn't satisfy this piece of test data, that is OK
And don't worry about votes or the winner yet, there is still more than a day left for this contest.
Vladdy
01-03-2003, 05:24 PM
Sorry, beetle, I should have read the rules more carefully.
The following reg ex seems to specify valid roman numeral format
vr=/^\s*m{0,3}(?:cm|cd|d)?c{0,3}(?:xc|xl|l)?x{0,3}(?:ix|iv|v)?i{0,3}\s*$/i;
See modifications to my submission in red
santigoon
01-03-2003, 05:41 PM
function rn2dec(str)
{
return p=v=e=0, m={M:1e3, D:5e2, C:1e2, L:50, X:10, V:5, I:1}, str.toUpperCase().replace( /./g, function(a){ q=p, p=m[a], e=((p==q)?e+1:0), v+=(e>2 || q && (p>q && p!=5*q && p!=10*q))?Number.NaN:((p>q)?p-q-q:p) }), v;
};
Okay. After some checking roman numeral rules and some simple calculus, it boils down to the line above.
Modification of the literal was not necessary since any character preceding(=q) the current character(=p), can only be five or ten times the numeric value of p or less than q. These conditions already impose the constraints for which the modification would be used. That is to prevent a IVX or IVM sequence.
Any sequence of equal characters can be at most three long (as is shown in the regexp from vladdy). So adding a sequence counter and the constraints is enough to create the new function.
In short it translates the current character to it's decimal equivalent. If it is higher than the preceding character, the preceding character was a subtraction and is applied as such. If not it is assumed to be an addition.
If any constraint is violated (unknown symbol, or the story above), the NaN is added. Since any number added to a NaN remains a NaN, no escaping is required.
The replace function is used as a shortened loop.
Few. I spent more time typing this then coding it.
santigoon
01-03-2003, 05:54 PM
Aaarg. Should have read the rules more closely. It fails a zero and VV test.
A oneliner is possible, but must incorporate the regexp Vladdy proposed, combined with a replace function. Since most of this has already been posted by Vladdy, votes go to him (even if he fails the 0 test as well (rn2dec("")).
Vladdy
01-03-2003, 06:16 PM
I got this idea after I put together the regular expression
posted above. I remember that multiple entries do not
count (c'mon beetle, these are just bragging rights at stake,
would you loosen up them rules a bit?), but figured
it was worth publishing...
As far as the "" and "0" goes, since roman numerals can only be positives the return of 0 means error ;^)
...shooting for a one-liner (lets see the limits to the scroll hehe):
function rn2dec(str)
{ return !(a=/^\s*(m{0,3})(cm|cd|d?)(c{0,3})(xc|xl|l?)(x{0,3})(ix|iv|v?)(i{0,3})\s*$/.exec(str.toLowerCase()))?0:a[1].length*1000 + (a[2].length==0?0:(a[2][0]=='c'?(a[2][1]=='m'?900:400):500)) + a[3].length*100 + (a[4].length==0?0:(a[4][0]=='x'?(a[4][1]=='c'?90:40):50)) + a[5].length*10 + (a[6].length==0?0:(a[6][0]=='i'?(a[6][1]=='x'?9:4):5)) + a[7].length;
}
Doing the same in a more readable fashion:
function rn2dec(str)
{ vr=/^\s*(m{0,3})(cm|cd|d?)(c{0,3})(xc|xl|l?)(x{0,3})(ix|iv|v?)(i{0,3})\s*$/;
a=vr.exec(str.toLowerCase());
if(!a) return 0;
return a[1].length*1000 + (a[2].length==0?0:(a[2][0]=='c'?(a[2][1]=='m'?900:400):500))
+ a[3].length*100 + (a[4].length==0?0:(a[4][0]=='x'?(a[4][1]=='c'?90:40):50))
+ a[5].length*10 + (a[6].length==0?0:(a[6][0]=='i'?(a[6][1]=='x'?9:4):5))
+ a[7].length;
}
mordred
01-03-2003, 06:47 PM
Hehe, I knew there were more things to converting Roman numbers than just direct replacement by decimal numbers... partly because I knew that Mark Pilgrim has written this whole chapter about his sample Python app that does this job. Not that I know this particular chapter or how his algorithm works (then I would not post such crap as I did).
Anyway, I recalled that Roman numbers couldn't be repeated more than three times, but your first test example confused the heck out of me. ;) So I changed my regexp to acommodate that. I did not know though that 5's-characters couldn't be repeated and that you can only put the I infront of V or X to get a 4 / 9. I guess I brush up my knowledge of Roman numbers and eventually return to the challenge, but I might not do so because I have already submitted (a not-so-good try), and I don't want to put myself in advantage to those who remembered and adhered to the "specs" and still gnaw at their algorithm and therefore have'nt submitted until now.
Happy coding everyone! :)
ca_redwards
01-03-2003, 07:18 PM
Line breaks added for readability only:
function rn2dec(str)
{ return
rnv=[1000,500,100,50,10,5,1],
rnd='MDCLXVI',
i0=rnd.indexOf(str.charAt(0)),
i1=rnd.indexOf(str.charAt(1)),
sgn=((i0-i1)<3)?(i1>=i0?1:-1):'?',
str.length?(rnv[i0]*((str.length>1)?sgn:1)+rn2dec(str.slice(1))):0
}
A valid roman numeral is converted to its decimal equivalent.
An invalid roman numeral returns NaN.
An empty string returns 0.
Checking against test cases...
Hmmm! Say, why isn't MCVIX invalid? Is it really 1114?
M+C+V+IX = 1000+100+5+9
I guess 1114 should be written as MCXIV...
Nuts!
Arielladog
01-03-2003, 07:26 PM
The only reason why I'm submitting this is because it works (I think) and almost anyone should be able to read the code and understand it.
function rn2dec(str){
var str=str.toUpperCase(), total = 0, values = {M:1000,D:500,C:100,L:50,X:10,V:5,I:1}, letters = new Array("M","D","C","L","X","V","I");
function upTo(letter){
var val = 0;
if(str.indexOf(letters[letter]) == -1) return val;
var work = str.substr(0,str.lastIndexOf(letters[letter])+1);
str = str.substr(str.lastIndexOf(letters[letter]) + 1, str.length);
for(k=0;k<work.length;k++){
if(work.charAt(k) == letters[letter]) val+=values[letters[letter]];
else if(k==work.length-2 && work.charAt(work.length-2) != letters[letter]){
var toCheck = ((letter+1)%2) == 0 ? (letter+1) : letter+2;
if(toCheck>6) return "NaN";
if(work.charAt(work.length-2) == letters[toCheck]) val-=values[letters[toCheck]];
else return "NaN";
}else return "NaN";
}
if((letters[letter] == "C" || letters[letter] == "X" || letters[letter] == "I") && val >= 4*values[letters[letter]])return "NaN";
if((letters[letter] == "D" || letters[letter] == "L" || letters[letter] == "V") && val >= 2*values[letters[letter]])return "NaN";
return val;
}
for(j = 0; j<letters.length; j++) total+=upTo(j);
return total.toString().indexOf("NaN")!=-1 ? "NaN" : parseInt(total);
}
*edit* added the toUppserCase() thing *edit*
P.S.-I've never been big on RegExp :D
aDog :cool:
Borgtex
01-03-2003, 07:53 PM
I feel a presence I’ve not felt since…
Hi Arielladog! :)
ca_redwards
01-03-2003, 08:49 PM
This gives a lot of wrong results!
MMMMMMMMMMMMCCCXLV=12345 (0?)
MCMLXXVIII=1978 (1578?)
CMXCIX=999 (555?)
MCDXCII=1492 (1552?)
MCXI=1111
MMIII=2003
MMMCMXXXIX=3939 (3535?)
MDCCLXXVI=1776
LXIV=64 (65?)
DLV=555
VC=NaN (0?)
MCVIX=NaN (0?)
Originally posted by Vladdy
I got this idea after I put together the regular expression
posted above. I remember that multiple entries do not
count (c'mon beetle, these are just bragging rights at stake,
would you loosen up them rules a bit?), but figured
it was worth publishing...
As far as the "" and "0" goes, since roman numerals can only be positives the return of 0 means error ;^)
...shooting for a one-liner (lets see the limits to the scroll hehe):
function rn2dec(str)
{ return !(a=/^\s*(m{0,3})(cm|cd|d?)(c{0,3})(xc|xl|l?)(x{0,3})(ix|iv|v?)(i{0,3})\s*$/.exec(str.toLowerCase()))?0:a[1].length*1000 + (a[2].length==0?0:(a[2][0]=='c'?(a[2][1]=='m'?900:400):500)) + a[3].length*100 + (a[4].length==0?0:(a[4][0]=='x'?(a[4][1]=='c'?90:40):50)) + a[5].length*10 + (a[6].length==0?0:(a[6][0]=='i'?(a[6][1]=='x'?9:4):5)) + a[7].length;
}
Doing the same in a more readable fashion:
function rn2dec(str)
{ vr=/^\s*(m{0,3})(cm|cd|d?)(c{0,3})(xc|xl|l?)(x{0,3})(ix|iv|v?)(i{0,3})\s*$/;
a=vr.exec(str.toLowerCase());
if(!a) return 0;
return a[1].length*1000 + (a[2].length==0?0:(a[2][0]=='c'?(a[2][1]=='m'?900:400):500))
+ a[3].length*100 + (a[4].length==0?0:(a[4][0]=='x'?(a[4][1]=='c'?90:40):50))
+ a[5].length*10 + (a[6].length==0?0:(a[6][0]=='i'?(a[6][1]=='x'?9:4):5))
+ a[7].length;
}
Vladdy
01-03-2003, 08:57 PM
hmm... it actually does... but only in damn IE...
looking for a reason... stand by....
here is the correction that works in both IE and Moz.
function rn2dec(str)
{ vr=/^\s*(m{0,3})(cm|cd|d?)(c{0,3})(xc|xl|l?)(x{0,3})(ix|iv|v?)(i{0,3})\s*$/;
a=vr.exec(str.toLowerCase());
if(!a) return 0;
return a[1].length*1000 + (a[2].length==0?0:(a[2].charAt(0)=='c'?(a[2].charAt(1)=='m'?900:400):500))
+ a[3].length*100 + (a[4].length==0?0:(a[4].charAt(0)=='x'?(a[4].charAt(1)=='c'?90:40):50))
+ a[5].length*10 + (a[6].length==0?0:(a[6].charAt(0)=='i'?(a[6].charAt(1)=='x'?9:4):5))
+ a[7].length;
}
It returns zero on error.
beetle
01-03-2003, 09:09 PM
Ok, challenge status update. Grading scale 1 (lowest) to 10(highest)
Roelf
Awaiting redo - Good short function, although he missed correctly initializing variables on one line, I know what he intended. Accepts non-valid roman numerals, however. 6 lines, 15 actual.
Algorithm
Awaiting redo - Accepts improper roman numerals. Good function at only 2 lines
santigoon
8 - Accept some improper roman numerals. Excellent as a one-liner
mordred
4 - Long but yes, very readable code. Accepts improper roman numerals. Extra point for making a method :thumbsup: Did I mention long?
Vladdy 1st post
7 - Short and readable. Accepts one type of improper numeral (IXI). Yes, I know it's not in the test data, but it IS an invalid roman numeral ;)
Vladdy 2nd post
Not being graded
ca_redwards
8 - Accept some improper roman numerals. Excellent as a one-liner. Kudos for using recursion.
adog
5 - Long but nice and readable. Fails the same numeral test as Vladdy's
If you have received a grade here, please stop posting ideas or changes or whatever. It's complicated enough tracking 6 submitters through 17 posts and testing on two browsers. In otherwords, I don't care about the could-haves and would-haves. You should-have tested :p
Remember, winners and the various consolation awards don't come until tomorrow!
I agree with Vladdy. The overall challenge winner should be responsible for posting the next challenge. :D
Vladdy
01-03-2003, 09:29 PM
Originally posted by beetle
Vladdy 1st post
7 - Short and readable. Accepts one type of improper numeral (IXI). Yes, I know it's not in the test data, but it IS an invalid roman numeral ;)
Just for the fun of it, here is the modified reg ex that should take care of this problem:
vr=/^\s*(m{0,3})((?:cm)(?!c)|(?:cd)(?!c)|d?)(c{0,3})((?:xc)(?!x)|(?:xl)(?!x)|l?)(x{0,3})((?:ix)(?!i)|(?: iv)(?!i)|v?)(i{0,3})\s*$/;
Originally posted by beetle
Vladdy 2nd post
Not being graded
How about "unofficial" grade :D :D :D
Borgtex
01-04-2003, 03:23 PM
If you have received a grade here, please stop posting ideas or changes or whatever
Does that means that Vladdy's last post doesn't counts?
I think he should be the winner ;)
beetle
01-04-2003, 04:37 PM
Yes, that's exactly what that means.
When was the last time you've seen a contest of ANY kind that let you enter and enter and enter, always building on your past mistakes and those of other participants until you had something that's almost perfect?
Sorry, only the 1st post from each member will be considered, and I made it VERY clear in the rules that multiple entries would disqualify the user.
After the contest is over, a collective effort can be made amongst the members to find THE best solution. But until then, any efforts made towards that end defeat the purpose of a challenge/contest.
Algorithm
01-05-2003, 09:32 AM
My resubmitted version now rejects all invalid Roman numerals, but allows the Julian variant (IIII is valid, but not XXXX), in honor of Julius, the first great Roman emperor, who happened to use it.
And it's still only in two lines!function rn2dec(str){
for(var i=(str.length-1),
a=str.toUpperCase().split(''),
r='IVXLCDM',b=-1,e=-2,c=0,f=-2,n=0;
i>=0;
c=r.indexOf(a[i]),
a[i]=((c>=0&&(c>b||c==e))?(((c>b)?(b=(c+c%2)-(((n=((c==f)?
n+1:1))>((c==6)?9e9:(c==0)?3:2))?0:1),e=(((c-f)<(3-f%2))?
-2:b-1),'+'):(e=-2,'-'))+((c<1)?'1':(c<2)?'5':(c<3)?
'10':(c<4)?'50':(c<5)?'100':(c<6)?'500':'1000')):'+NaN'),
f=c,i--);
return eval('0'+a.join(''));
}
Vladdy
01-05-2003, 04:55 PM
I see the comma operator is being abused just to keep the number of lines down.
IMHO the number of assignment operators is a much better parameter to judge script brevity.
beetle
01-06-2003, 02:44 PM
Ok. I'm sure that some of you have been waiting for this, so here are the results.
Nicest looking and most readable
Mordred. Props again for making a method, you were the only one who kept our namespace clean :thumbsup:
The one-liners
ca_redwards & santigoon. Although they accepted some improper numerals, they were the only valid one-line entries. Very nice, fellas :D
Longest Roman Numeral Regex I've Ever Seen
Vladdy ;)
Challenge Winner
Algorithm
Congrats everybody! Sorry this challenge proved to be uhh, ahem, a challenge, for some of you, but hey, it's been fun.
I suppose you'd like to see my solution.String.prototype.rn2dec= function()
{
for ( var a, b, v=0, t={M:1000, D:500, C:100, L:50, X:10, V:5, I:1}, i=this.length-1; (a=this.charAt(i)); i--) b = this.charAt(i+1), v += (typeof t[b] == 'undefined' || t[a] >= t[b]) ? t[a] : -(t[a]);
return (/^M*(D?C?C?C?|C[MD])(L?X?X?X?|X[CL])(V?I?I?I?|I[XV])$/i.test( this )) ? v : Number.NaN;
}Well, that's it! I suppose if we proceed as Vladdy and I agree, the Algorithm is responsible for posting the next challenge. Good luck Algorithm, this takes a bit of work! :p
P.S. Vladdy, what you say may be true, but that is not how this challenge was ruled. I did not expect to see so much use of the comma operator outside of loops as I have seen here. Alas, I allowed shorthand, so this is all valid.
vBulletin® v3.8.2, Copyright ©2000-2012, Jelsoft Enterprises Ltd.