Coding Challenge Of The Day
-
for well-formed roman numerals, modern rules:
int r2d2(const char *r)
{
int val[128];
memset(val,0,sizeof(int)*128);
val['I']=1; val['V']=5;
val['X']=10; val['L']=50;
val['C']=100; val['D']=500; val['M']=1000;int a = 0;
for (int cv, pv = 0, i=strlen(r)-1;i>=0;i--)
{
cv = val[r[i]];
a += cv * (pv > cv ? -1 : 1);
pv = cv;
}return a;
}
Seems a waste of RAM.
-
I once met a well formed roman, when I was touring through Italy. :cool:
Chris Meech I am Canadian. [heard in a local bar] In theory there is no difference between theory and practice. In practice there is. [Yogi Berra] posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
did you get here number?
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
Apologies if other respondents have used a similar technique, but I have deliberately not looked at the other replies before attempting this challenge so that I am not influenced by other people's ideas. The following is in JavaScript, not obfuscated. The tricks are: Using an object literal as a lookup table and treating the double chars as subtractors from the second single chars (e.g. CM = [CM] + [M] = -100 + 1000 = 900). The only awkward part is preventing the last char being counted twice - once as a single char and once as a double char with no second char (this is done by appending '?').
// Roman to Arabic character translations
function RtoA(r) // r is roman numerals in any case
{
// Roman to Arabic conversion table
var Rch =
{
// Single chars: Add each value separately to the total
I: 1, V: 5, X: 10, L: 50, C: 100, D: 500, M: 1000,
// Double chars: Modify the sum of the second char as subtractors
CM: -100, CD: -100, XC: -10, XL: -10, IX: -1, IV: -1
};var R = r.toUpperCase(); // Ignore case var A = 0; // Arabic equivalent // Parse the text converting valid single chars and double chars // Set any invalid single or double char combinations as translating to zero for (var i = 0; i < R.length; i++) { var ch = R.charAt(i); A += Rch\[ch + (R.charAt(i + 1) || '?')\] // Double char conversion || Rch\[ch\] // Single char conversion || 0; // No conversion - invalid char }; // for return A;
}
alert(RtoA('MDC')); // 1600
alert(RtoA('mcmxcix')); // 1999 -
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
First time post so hope this looks OK; 1 CRT "NUMERALS: ": ; INPUT NUM 2 CRT "NUMBER : ":ICONV(NUM, 'NR') 3 END Written in UniVerse BASIC.
-
Or, somewhat more tersely,
def r2d3(r,(s,M,C,X,I,z,V,L,D)=["%%s%d"%v for v in[1001,1000,100,10,1,0,5,50,500]]):
return eval("".join([
p%"+-"[eval( p%"%s>"%d%"")]
for d,p in zip(map(eval,'%sz'%r),map(eval,'s%s'%r))
][1:]))Or, somewhere in between:
def a6(roman):
if len(roman)==0:
return 0
mapping={"I":1,"V":5,"X":10,"L":50,"C":100,"D":500,"M":1000}
values=[mapping[digit] for digit in roman.upper()]
for i in range(len(values)):
if ialso, added capitalization tolerance, so that "MCM" and "mcm" evaluate the same. I haven't added a check that the argument is a valid roman numeral, but that is left as an exercise to the reader ;P
Φευ! Εδόμεθα υπό ρηννοσχήμων λύκων!
(Alas! We're devoured by lamb-guised wolves!) -
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
I hope it will be obscure enough. ;)
class Program
class Program
{
static int RomanToArabic(string r)
{
int x, y, z = x = y = 0;
foreach (char c in r)
y += ((z = (int)Math.Pow(10, (z = "ivxlcdm".IndexOf((char)(c | ' '))) / 2) * (1 + 4 * (z & 1))) > x ? -2 * x + (x = z) : x = z);
return y;
}static void Main(string\[\] args) { Console.WriteLine(RomanToArabic("MDC")); // 1600 Console.WriteLine(RomanToArabic("mcmxcix")); // 1999 Console.ReadKey(); } }
}
-
no arrays, no dictionaries, no obscure language, just some original coding:
public static bool TryParseRoman(string wellFormedRoman, out int val) {
val=0;
int prevDigit=0;
foreach (char c in wellFormedRoman) {
int index="IVXLCDM".IndexOf(c);
if (index<0) {val=0; return false;}
int digit=1;
int factor=5;
while (--index>=0) { digit*=factor; factor=7-factor; }
if (prevDigitBTW: is it Friday already?
:)
Luc Pattyn [My Articles] Nil Volentibus Arduum
This is definitely better than my attempt.
-
I hope it will be obscure enough. ;)
class Program
class Program
{
static int RomanToArabic(string r)
{
int x, y, z = x = y = 0;
foreach (char c in r)
y += ((z = (int)Math.Pow(10, (z = "ivxlcdm".IndexOf((char)(c | ' '))) / 2) * (1 + 4 * (z & 1))) > x ? -2 * x + (x = z) : x = z);
return y;
}static void Main(string\[\] args) { Console.WriteLine(RomanToArabic("MDC")); // 1600 Console.WriteLine(RomanToArabic("mcmxcix")); // 1999 Console.ReadKey(); } }
}
Nice. I like the
% ' '
bits, and appreciate you used literalVII
. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
-
Nice. I like the
% ' '
bits, and appreciate you used literalVII
. :)Luc Pattyn [My Articles] Nil Volentibus Arduum
oops I removed the
% ' '
... Ok I put back a:"ivxlcdm".IndexOf((char)(c | ' '))
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
This is my final answer
static int RomanToArabic(string roman, int x = 0, int y=0)
{
return roman.Length == 0 ? 0 : (y = (int)Math.Pow(10, (y = "ivxlcdm".IndexOf((char)(roman[0] | ' '))) / 2) * (1 + 4 * (y & 1))) + (y > x ? -2 * x : 0) + RomanToArabic(roman.Substring(1), y);
} -
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
Geez, I thought it was going to be something hard.
"Microsoft -- Adding unnecessary complexity to your work since 1987!"
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
OK, I admit it isn't very small. Scala is number 46 on the Tiobe Index this month, so perhaps it is obscure enough to qualify. Being a "functional" language there are actually 3 functions but I nested them in one.
def convertRomanToArabic(romanNumeral: String): Int = { var previous = 0 def convertSingleRomanNumeral(numeral: Char): Int = { numeral match { case 'I' => 1 case 'V' => 5 case 'X' => 10 case 'L' => 50 case 'C' => 100 case 'D' => 500 case 'M' => 1000 } } def addRomans(next: Int, accumulator: Int): Int = { if (previous == 0) previous = accumulator var addto = if (previous > next) next \* -1 else next previous = next accumulator + addto } val values = romanNumeral.toList.map(n => convertSingleRomanNumeral(n)) values.reduceRight(addRomans) }
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
FUNCTION Roman2Dec(cRoman)
LOCAL nPointer := len(cRoman) LOCAL nPos := 0,nFaceVal := 0,nLastVal := 0, nReturn := 0 WHILE nPointer > 0 nPos := at(substr(cRoman, nPointer, 1),'IVXLCDM') -1 nFaceVal := (10 ^ int((nPos)/2)) \* (1+((nPos) % 2 \* 4)) nReturn += iif(nFaceVal < nLastVal, -nFaceVal, nFaceVal) IF nFaceVal > nLastVal nLastVal := nFaceVal ENDIF nPointer-- ENDDO
RETURN nReturn
-
for well-formed roman numerals, modern rules:
int r2d2(const char *r)
{
int val[128];
memset(val,0,sizeof(int)*128);
val['I']=1; val['V']=5;
val['X']=10; val['L']=50;
val['C']=100; val['D']=500; val['M']=1000;int a = 0;
for (int cv, pv = 0, i=strlen(r)-1;i>=0;i--)
{
cv = val[r[i]];
a += cv * (pv > cv ? -1 : 1);
pv = cv;
}return a;
}
These aren't the roman numerals you're looking for. You should go about your business. Move along move along.
ragnaroknrol: Yes, but comparing a rabid wolverine gnawing on your face while stabbing you with a fountain pen to Vista is likely to make the wolverine look good, so it isn't exactly that big of a compliment.
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
In C#:
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;namespace RomanNumerConverter
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}private void button1\_Click(object sender, EventArgs e) { Hashtable ht = new Hashtable(); // Create a look-up table to look up Roman numerals and get there associated values. ht.Add('M', 1000); ht.Add('D', 500); ht.Add('C', 100); ht.Add('L', 50); ht.Add('X', 10); ht.Add('V', 5); ht.Add('I', 1); String RomanNumber = textBox1.Text; int value = 0; for (int index = 0; index < RomanNumber.Length; index++) // Go through the entered Roman numeral a character at a time { int nextVal; int currentVal = Convert.ToInt32(ht\[RomanNumber\[index\]\]); // Get the value of the current character. if (index + 1 < RomanNumber.Length) // if you are not at the end of the string { nextVal = Convert.ToInt32(ht\[RomanNumber\[index + 1\]\]);// Peek at the next number to see you need to use it to combine characters for a single value(e.g. IV equates to 4) } else { nextVal = 0; // No more characters so just set this to 0 to simplfy the algorithm. } if (nextVal > currentVal)// If the value of nextVal is greater than currentVal, we have a subtractive situation (e.g. IV) { currentVal = nextVal - currentVal; // To determine the value you have to subtract the value of the first number of the pair from the second number(e.g. IV = 5 - 1 = 4) index++;// Used nextVal to help determine the number so increment the index to skip over that character in the next iteration. } value += currentVal; // Add the values of the Roman numerals up. } label1.Text = value.ToString(); //Convert the sum to string to use as a text label. This is the converted number in Arabic numerals. } }
}
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
Hideous C# one-liner* with whitespace added to ahahahaha enhance readability.
static double RomanToInt( string roman ) {
return (
Enumerable.Range( 0, 3 )
.Select(
i =>
( i + 1 ) * 2 - 2
)
.Aggregate(
roman.ToLower(),
( current, i ) =>
current
.Replace(
"ivxlcdm".Substring( i, 2 ),
new string( "ivxlcdm"[ i ], 4 )
)
.Replace(
"ivxlcdm"[ i ].ToString() + "ivxlcdm"[ i + 2 ].ToString(),
"ivxlcdm"[ i + 1 ].ToString() + new string( "ivxlcdm"[ i ], 4 )
)
)
.Select(
i =>
"ivxlcdm".IndexOf( i )
)
.Select(
x =>
x % 2 == 0 ?
Math.Pow( 10, x / 2 ) :
Math.Pow( 10, ( x + 1 ) / 2 ) / 2
)
.Sum()
);
}*Not counting the function declaration - trivial to convert to a true a one-liner but you asked for a function
-
Hideous C# one-liner* with whitespace added to ahahahaha enhance readability.
static double RomanToInt( string roman ) {
return (
Enumerable.Range( 0, 3 )
.Select(
i =>
( i + 1 ) * 2 - 2
)
.Aggregate(
roman.ToLower(),
( current, i ) =>
current
.Replace(
"ivxlcdm".Substring( i, 2 ),
new string( "ivxlcdm"[ i ], 4 )
)
.Replace(
"ivxlcdm"[ i ].ToString() + "ivxlcdm"[ i + 2 ].ToString(),
"ivxlcdm"[ i + 1 ].ToString() + new string( "ivxlcdm"[ i ], 4 )
)
)
.Select(
i =>
"ivxlcdm".IndexOf( i )
)
.Select(
x =>
x % 2 == 0 ?
Math.Pow( 10, x / 2 ) :
Math.Pow( 10, ( x + 1 ) / 2 ) / 2
)
.Sum()
);
}*Not counting the function declaration - trivial to convert to a true a one-liner but you asked for a function
Sweet.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
-
Sweet.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
Better:
static int RomanToInt( string roman ) {
return roman
.ToLower()
.Select(
n =>
new Dictionary {
{'i', 1},
{'v', 5},
{'x', 10},
{'l', 50},
{'c', 100},
{'d', 500},
{'m', 1000},
}[ n ]
)
.Aggregate(
new[] {0, 0, 0},
( c, d ) =>
new[] {
c[ 0 ] + ( d > c[ 2 ] ? d - c[ 1 ] : c[ 1 ] ),
d > c[ 2 ] ? 0 : d,
d
}
)
.Take( 2 )
.Sum();
} -
FUNCTION Roman2Dec(cRoman)
LOCAL nPointer := len(cRoman) LOCAL nPos := 0,nFaceVal := 0,nLastVal := 0, nReturn := 0 WHILE nPointer > 0 nPos := at(substr(cRoman, nPointer, 1),'IVXLCDM') -1 nFaceVal := (10 ^ int((nPos)/2)) \* (1+((nPos) % 2 \* 4)) nReturn += iif(nFaceVal < nLastVal, -nFaceVal, nFaceVal) IF nFaceVal > nLastVal nLastVal := nFaceVal ENDIF nPointer-- ENDDO
RETURN nReturn
My previous code after some Herbalife:-
FUNC rr(c)
r=0;p=0;b=len(c)
WHILE b>0
v=at(c[b],'IVXLCDM')-1
f=10^int(v/2)*(v%2*4+1)
r+=if(fp,p:=f,)
b--
END
RETURN rCompiles with xHarbour.
-
Write a function to convert Roman numerals to Arabic numbers. The smaller the better. Bonus points, as always, for obscure languages and obfuscated assembler.
cheers, Chris Maunder The Code Project | Co-founder Microsoft C++ MVP
private Dictionary R2A_dictionary = new Dictionary()
{
{'I', 1},
{'V', 5},
{'X', 10},
{'L', 50},
{'C', 100},
{'D', 500},
{'M', 1000},
};private int ConvertRomanToArabic(string roman)
{
int result = 0;
int previous = Int32.MaxValue, current = 0;
for (int i = 0; i < roman.Length; i++)
{
current = R2A_dictionary[roman[i]];
result += current;
if (current > previous)
result -= previous << 1;
previous = current;
}
return result;
}