Code Golf New Year Edition - Integer to Roman Numeral
Asked Answered
C

31

17

Write a program that take a single command line argument N and prints out the corresponding Roman Numeral.

Eg N = 2009 should print MMIX.

Let's say this should work for 0 < N < 3000.

(Had fun playing my first ever round of code golf with the Christmas edition, and thought this could fit for New Year. Googled to see if this has come up before elsewhere and it looks like it hasn't, but let me know if this is too hard or too easy or if the rules need changing. )

Happy MMIX!

Concision answered 27/12, 2008 at 2:21 Comment(1)
www-cs-faculty.stanford.edu/~knuth/mmix.htmlHungerford
G
17

Perl: 69 strokes (count 'em!)

Sixty-nine strokes including calling perl in the first place:

$ perl -ple's!.!($#.=5x$&*8%29628)=~y$IVCXL4620-8$XLMCDIXV$d!eg;last}{'
3484
MMMCDLXXXIV
  • Reads a single line, writes a single line.
  • Works from 0 to 3999, inclusive. (Prints empty string for 0.)
  • In Perl golf competitions, this is usually scored as 62 strokes = 58 for the code + 4 for the switches.
  • Why, yes, those are mismatched braces. Thanks for asking. =)

Credits: originally due to Ton Hospel. The trick involving the mismatched braces is from rev.pl in this post (which incidentally, is ingenious).

Grosmark answered 27/12, 2008 at 2:21 Comment(1)
You should remove ;last}{ and save 7 chars. Furthermore i think you have not to take into account the invocation of perl interpreter, so you save 5 chars more. Count is then 57 chars !Riesling
H
14

In C#, as an extension method to Int32:

public static class Int32Extension {
    public static string ToRomanNumeral(this int number) {
        Dictionary<int, string> lookup = new Dictionary<int, string>() {
            { 1000000, "M_" },
            { 900000, "C_D_" },
            { 500000, "D_" },
            { 400000, "C_D_" },
            { 100000, "C_" },
            { 90000, "X_C_" },
            { 50000, "L_" },
            { 40000, "X_L_" },
            { 10000, "X_" },
            { 9000, "MX_"},
            { 5000, "V_" },
            { 4000, "MV_" },
            { 1000, "M" },
            { 900, "CM" },
            { 500, "D" },
            { 400, "CD" },
            { 100,"C" },
            { 90, "XC" },
            { 50, "L" },
            { 40, "XL" },
            { 10, "X" },
            { 9, "IX" },
            { 5, "V" },
            { 4, "IV" },
            { 1, "I" }
        };

        StringBuilder answer = new StringBuilder();
        foreach (int key in lookup.Keys.OrderBy(k => -1 * k)) {
            while (number >= key) {
                number -= key;
                answer.Append(lookup[key]);
            }
        }
        return answer.ToString();
    }
}

The underscores should be overlines above the respective letter to be true Roman Numeral.

Herd answered 27/12, 2008 at 2:49 Comment(4)
+1 for being the only answer which considers the higher-order roman symbols.Ri
This code works, but there is no guarantee it will in .NET 4.0, since the order in which Dictionary produces its keys is undefined. It just so happens to work in this example. I would change the code to use a List instead, to guarantee the outcome.Trabue
@Lasse V. Karlsen: Addressed.Herd
For code golf, are you allowed to save characters by using 'var'?Approximate
R
11

Common lisp (SBCL). 63 characters counted by "wc -c".

(format t "~@R~%" (parse-integer (elt *posix-argv* 1)))
(quit)

This only works for numbers upto 3999.

Reexamine answered 27/12, 2008 at 2:55 Comment(3)
using a build-in in is cheating ;-)Melosa
Nobody ever says that about Perl regular expressions. If it's trivial for a language to do something, you should do it. That's part of what makes coding it an art.Stratum
Indeed, using Perl, it suffices to use 62 characters. See my post below.Grosmark
S
6

C#: 179 chars (not including spaces/tabs)

    static string c(int a)
    {
        int[] v = { 1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1 };
        var s = ""; 
        for ( var i = 0; i < 13; i++ )
            while (a >= v[i])
            {
                a -= v[i];
                s += "M CM D CD C XC L XL X IX V IV I".Split()[i];
            }
        return s;
    }
Sabulous answered 27/12, 2008 at 2:21 Comment(2)
I think if you delimited your numerals with a space instead of a pipe you could just call Split() without an argument.Assignee
@Phil Thanks, I learned something new today :) I never knew that worked. It makes me wonder how many times I've used split with needless params in the past.Sabulous
D
5

Language: JavaScript.

129 chars without the added formatting

The following code is a result of coding quiz which which took place at pl.comp.lang.javascript newsgrup several years ago. I'm not the author of the code.

function rome(N,s,b,a,o){
  for(s=b='',a=5;N;b++,a^=7)for(o=N%a,N=N/a^0;o--;)
  s='IVXLCDM'.charAt(o>2?b+N-(N&=~1)+(o=1):b)+s;return s
}

Original post by Elus

Daren answered 27/12, 2008 at 2:21 Comment(0)
H
5

Perl, 19 strokes. Guaranteed to work for values between 1 and 12.

sub r{chr 8543+pop}
Hungerford answered 27/12, 2008 at 2:21 Comment(0)
G
4

Language: C, Char count: 174

#define R(s,v)for(;n>=v;n-=v)printf(#s);
main(int n,char**a){n=atoi(a[1]);R(M,1000)R(CM,900)R(D,500)R(CD,400)R(C,100)R(XC,90)R(L,50)R(XL,40)R(X,10)R(IX,9)R(V,5)R(IV,4)R(I,1)}
Gretchengrete answered 27/12, 2008 at 2:21 Comment(2)
Could you not further reduce it by making R a function (like I did for 'n' in my answer)?Foah
Ah, nevermind -- I see your trick with string'ing using the macro. Crafty. =]Foah
Y
4

Python, 173 bytes.

r=lambda n:o[n]if n<10 else''.join(dict(zip('ivxlc','xlcdm'))[c]for c in r(n//10))+o[n%10]
o=' i ii iii iv v vi vii viii ix'.split(' ')
import sys
print r(int(sys.argv[1]))

(I first saw this algorithm in Gimpel's Algorithms in Snobol4; Snobol expressed it more elegantly.)

Yate answered 27/12, 2008 at 2:21 Comment(1)
This is great! Recursive application on n//10 is a much more terse and effective usage of the independence between digits than simply popping one off at a time, most significant first.Execration
F
3

A simple Haskell version, that still keeps clarity. 205 characters, including white space.

l = ["M","CM","L","CD","C","XC","L","XL","X","IX","V","IV","I"]
v = [1000,900,500,400,100,90,50,40,10,9,5,4,1]
roman n i
    | n == 0 = ""
    | n >= v!!i = l!!i ++ roman (n-v!!i) i
    | otherwise = roman n (i+1)
Flinger answered 27/12, 2008 at 2:21 Comment(0)
V
3

Pike

60 characters, valid for 0 to 10000:

int main (int c, array a) {
    write(String.int2roman((int)a[1]));
}
Vantage answered 27/12, 2008 at 2:21 Comment(1)
just feels like cheating :)Amando
L
3

Perl 5.10

perl -nE'@l=qw{1 I 4 IV 5 V 9 IX 10 X 40 XL 50 L 90 XC 100 C 400 CD 500 D 900 CM 1000 M};
$o="";while(@l){$o.=pop(@l)x($_/($c=pop @l));$_%=$c;}say$o'

You input a line, it gives you the Roman numeral equivelent. This first version even lets you input more than one line.

Here is a shorter version that only works for one line, and ignores edge cases. so 4 becomes IIII instead of IV.

perl -nE'@l=qw{1 I 5 V 10 X 50 L 100 C 500 D 1000 M};
while(@l){$o.=pop(@l)x($_/($c=pop @l));$_%=$c;}say$o'

Here is what the first version would look like as a Perl script.

use 5.010;
while(<>){
  @l=qw{1 I 4 IV 5 V 9 IX 10 X 40 XL 50 L 90 XC 100 C 400 CD 500 D 900 CM 1000 M};
  $o="";
  while(@l){
    $o .= pop(@l) x ($_/($c=pop @l));
    # $l = pop @l;
    # $c = pop @l;
    # $o .= $l x ($_/$c);

    $_ %= $c;
  }
  say $o;
}
Luckily answered 27/12, 2008 at 5:57 Comment(3)
Does Perl actually guarantee left-to-right execution order? I know it "works in this implementation", but is it actually guaranteed (e.g., Java guarantees it)? Curious. For example, in C, the right-hand pop is just as likely as the left-hand one to be executed first.Hungerford
For infix operators, like x, the left side is evaluated before the right side.Luckily
I was going to post a Unicode version that would work for any positive integer, unfortunately it seems to be extremely difficult.Luckily
D
2

J, 20 characters!

'MDCLXVI'#~(7$5 2)#:

Usage:

   'MDCLXVI'#~(7$5 2)#: 2009
MMVIIII

Okay, it doesn't do subtraction properly, but hey it's pretty cool!

Explanation;

(7$5 2)

This takes the right argument (the list 5 2) and turns it into a list of size 7 - namely 5 2 5 2 5 2 5.

(7$5 2)#: 2009

This does the "anti-base" operation - basically doing iterative div and mod operations, returning the list 2 0 0 0 0 0 1 4.

Then #~ uses the previous list as a tally to pull corresponding characters out of 'MDCLXVI'.

Diedrediefenbaker answered 27/12, 2008 at 2:21 Comment(0)
N
2

I'm no Haskell expert, and this is too long to be a winner, but here's a solution I wrote a while back to solve Euler #89.

toRoman 0 = ""
toRoman 1 = "I"
toRoman 2 = "II"
toRoman 3 = "III"
toRoman 4 = "IV"
toRoman n
| n >= 1000 = repeatRoman 'M' 1000
| n >= 900 = subtractRoman "CM" 900
| n >= 500 = subtractRoman "D" 500
| n >= 400 = subtractRoman "CD" 400
| n >= 100 = repeatRoman 'C' 100
| n >= 90 = subtractRoman "XC" 90
| n >= 50 = subtractRoman "L" 50
| n >= 40 = subtractRoman "XL" 40
| n >= 10 = repeatRoman 'X' 10
| n >= 9 = subtractRoman "IX" 9
| n >= 5 = subtractRoman "V" 5
| otherwise = error "Hunh?"
where
    repeatRoman c n' = (take (n `div` n') (repeat c)) ++ (toRoman $ n `mod` n')
    subtractRoman s n' = s ++ (toRoman $ n - n')
Nessus answered 27/12, 2008 at 2:21 Comment(0)
C
2

Ruby, 136 chars

n = $*[0].to_i
for k,v in [1e3,900,500,400,100,90,50,40,10,9,5,4,1].zip %w{M CM D CD C XC L XL X IX V IV I}
  until n < k
    n -= k
    print v
  end
end
Confederacy answered 27/12, 2008 at 2:21 Comment(1)
Nice! You could shorten the inner loop with this stupid trick [$><<v, n-=k] until n<k.Hectogram
C
2

Language: dc (through shell) Char count:122

EDIT: q is equivalent of 2Q

dc -e '[I]1[IV]4[V]5[IX]9[X]10[XL]40[L]50[XC]90[C]100[CD]400[D]500[CM]900[M]?1000[szsz2Q]sq[~Sa[d0!<qrdPr1-lbx]dsbxLarz3<c]dscx10P' <<<$1

EDIT: two more chars by optimizing main loop stack manipulations

dc -e '[I]1[IV]4[V]5[IX]9[X]10[XL]40[L]50[XC]90[C]100[CD]400[D]500[CM]900[M]?1000[szsz2Q]sq[~Sa[d0!<qrdPr1-lbx]dsbxLarz3<c]dscx10P' <<<$1

EDIT: save 2 chars

dc -e '[I]1[IV]4[V]5[IX]9[X]10[XL]40[L]50[XC]90[C]100[CD]400[D]500[CM]900[M]1000?[sz2Q]sq[r~r[d0!<qSardPrLa1-lbx]dsbxrszz2<c]dscx10P' <<<$1

Previous version:

dc -e '[I]1[IV]4[V]5[IX]9[X]10[XL]40[L]50[XC]90[C]100[CD]400[D]500[CM]900[M]1000?[sz2Q]sq[r~r[d0!<qSaSadPLaLa1-lbx]dsbxrszz2<c]dscx10P' <<<$1
Carvel answered 27/12, 2008 at 2:21 Comment(0)
I
2

In Python - taken from ActiveState (credits: Paul Winkler) and compressed a bit:

def int2roman(n):
   if not 0 < n < 4000: raise ValueError
   ints = (1000, 900,  500, 400, 100,  90, 50,  40, 10,  9,   5,  4,   1)
   nums = ('M',  'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')
   result = ""
   for i in range(len(ints)):
      count = int(n / ints[i])
      result += nums[i] * count
      n -= ints[i] * count
   return result
Innis answered 27/12, 2008 at 2:21 Comment(1)
Nice - compressed down I get 293 bytes, including command-line arg reading. The implicit floor in integer division really saves some characters!Execration
H
2

Perl, 145 strokes (if you strip out all the newlines, which are optional), valid for 1..3999:

%t=qw(1000 M 900 CM 500 D 400 CD 100 C 90 XC 50 L 40 XL 10 X 9 IX 5 V 4 IV 1 I);
$d=pop;
for(sort{$b<=>$a}keys%t){$r.=$t{$_}x($d/$_);$d%=$_}
print$r

Some would say I could use say, but I don't have a say-capable Perl version here. Feel free to subtract 2 off the stroke count if using say works. :-)

For non-Perl programmers, this program exploits a number of useful Perl features:

  1. Hashes are constructed from lists of even length.
  2. Lists of strings can be specified in a compact syntax, using qw.
  3. Strings can auto-coerce into integers, as used in the <=> comparison operator in sorting the keys.
  4. There is an x operator which makes copies of strings/lists. Unfortunately for golfing here, x has identical precedence to /; if / were higher, the brackets would have been optional too.
Hungerford answered 27/12, 2008 at 5:41 Comment(1)
You can squeeze out a few characters by doing the sorting yourself. (Bonus teaching: hash slice assignment) Also, stmt mod 'for' saves 2 chars. @d=(1000,900,500,400,100,90,50,40,10,9,5,4,1);@r{@d}=qw(M CM D CD C XC L CL X IX V IV I);$d=pop;$r.=$r{$_}x($d/$_),$d%=$_ for@d;print$rInstinctive
L
1

Excel 8 chars (not lincluding the number):

=ROMAN(N)

Works up to 3000.

Tongue in cheek

Liles answered 27/12, 2008 at 2:21 Comment(1)
Now make it work with a command line argument as required. ;-)Defalcation
S
1

VB: 193 chars

Function c(ByVal a)
    Dim v() = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}
    Dim s = ""
    For i = 0 To 12
        While a >= v(i)
            a -= v(i)
            s += "M|CM|D|CD|C|XC|L|XL|X|IX|V|IV|I".Split("|")(i)
        End While
    Next
    Return s
End Function
Sabulous answered 27/12, 2008 at 2:21 Comment(1)
The newlines are significant in VB so you have to count themJosiahjosias
E
1

Python, 190 bytes. Based on snippet from ActiveState, via Federico.

A few small optimisations: removal of superfluous int() call, splitting string to get array, remove whitespace, ...

import sys
n=int(sys.argv[1])
N=(1000,900,500,400,100,90,50,40,10,9,5,4,1)
r=""
for i in range(len(N)):
 c=n/N[i]
 r+='M,CM,D,CD,C,XC,L,XL,X,IX,V,IV,I'.split(',')[i]*c
 n-=N[i]*c
print r

EDIT: superfluous, not spurious, and remove range check - thanks to Chris and dreeves! Stole idea of using symbol array inline from balabaster.

Execration answered 27/12, 2008 at 2:21 Comment(2)
You can throw out the range check too, and just say that the program works only for 1..3999, which is what my Perl one says, and the Common Lisp submission. :-PHungerford
You can remove the parens from N's assignment. You can also move the for onto a single line, separating the statements by semicolon. That will save you another 4 bytes.Chaperone
S
1

From a vaguely C-like language called LPC (precursor of Pike):

string roman_numeral(int val) {
    check_argument(1, val, #'intp);
    unless(val)
        return "N";
    string out = "";
    if(val < 0) {
        out += "-";
        val = -val;
    }
    if(val >= 1000) {
        out += "M" * (val / 1000);
        val %= 1000;
    }
    if(val >= 100) {
        int part = val / 100;
        switch(part) {
        case 9      :
            out += "CM";
            break;
        case 6 .. 8 :
            out += "D" + ("C" * (part - 5));
            break;
        case 5      :
            out += "D";
            break;
        case 4      :
            out += "CD";
            break;
        default     :
            out += "C" * part;
            break;
        }
        val %= 100;
    }
    if(val >= 10) {
        int part = val / 10;
        switch(part) {
        case 9      :
            out += "XC";
            break;
        case 6 .. 8 :
            out += "L" + ("X" * (part - 5));
            break;
        case 5      :
            out += "L";
            break;
        case 4      :
            out += "XL";
            break;
        default     :
            out += "X" * part;
            break;
        }
        val %= 10;
    }
    switch(val) {
    case 9      :
        out += "IX";
        break;
    case 6 .. 8 :
        out += "V" + ("I" * (val - 5));
        break;
    case 5      :
        out += "V";
        break;
    case 4      :
        out += "IV";
        break;
    default     :
        out += "I" * val;
        break;
    }
    return out;
}
Shogun answered 27/12, 2008 at 2:50 Comment(1)
That language taught me OOP back in 1992.Hectogram
F
0

Haskell, 245 charaters.

roman = numeral [(1000,"M"),(900,"CM"),(500,"D"),(400,"CD"),(100,"C"),(90,"XC"),
    (50,"L"),(40,"XL"),(10,"X"),(9,"IX"),(5,"V"),(4,"IV"),(1,"I")]
numeral [] n = ""
numeral ((m,c):xs) n = concat (replicate (n `div` m) c) ++ numeral xs (n `mod` m)
Frescobaldi answered 27/12, 2008 at 2:21 Comment(0)
C
0

Haskell version of my C#/LINQ answer, 234 chars:

main=putStrLn.foldr(\(y,x)s->concat[s,r(a x)(y!!2),r(a x*div x 5)(y!!0),r(abs(a x-div x 5))(y!!1),r(mod(mod x 5)4)(y!!2)])"".zip["XVI","CLX","MDC","  M"].map(read.(:[])).take 4.(++"000").reverse=<<getLine
r=replicate
a x=div(mod x 5)4
Canaigre answered 27/12, 2008 at 2:21 Comment(0)
C
0

In C# (running on .NET 4 RC), with 335 chars (if you remove the extraneous formatting).

using System;
using System.Linq;
class C
{
    static void Main()
    {
        Console.WriteLine(
                Console.ReadLine()
                .PadLeft(4,'0')
                .Select(d=>d-'0')
                .Zip(new[]{"  M","MDC","CLX","XVI"},(x,y)=>new{x,y})
                .Aggregate("",(r,t)=>r+
                                    new string(t.y[2],t.x%5/4)+
                                    new string(t.y[0],t.x%5/4*t.x/5)+
                                    new string(t.y[1],Math.Abs(t.x%5/4-t.x/5))+
                                    new string(t.y[2],t.x%5%4)));
    }
}

I know it does not beat the current best C# answer (182 chars) but this is just one big LINQ one-liner. Once I saw a raytracer written as a single LINQ query, I started approaching code golfs from this perspective.

Since this approach is functional, I'm working on a Haskell version of the same algorithm (will surely be shorter).

Canaigre answered 27/12, 2008 at 2:21 Comment(0)
B
0

Railo CFML - 53 chars, 46 without whitespace...

<cfoutput>
    #NumberFormat( N , 'roman' )#
</cfoutput>


Or, for other CF engines, not sure if these are shortest, but they'll do for now...


CFML - 350..453 characters:

<cffunction name="RomanNumberFormat">
    <cfset var D = ListToArray('M,CM,D,C,XC,L,X,IX,V,IV,I') />
    <cfset var I = [1000,900,500,100,90,50,10,9,5,4,1] />
    <cfset var R = '' />
    <cfset var x = 1 />
    <cfset var A = Arguments[1] />
    <cfloop condition="A GT 0">
        <cfloop condition="A GTE I[x]">
            <cfset R &= D[x] />
            <cfset A -= I[x] />
        </cfloop>
        <cfset x++ />
    </cfloop>
    <cfreturn R />
</cffunction>

<cfoutput>
    #RomanNumberFormat(N)#
</cfoutput>


CFScript - 219..323 characters:

<cfscript>
    function RomanNumberFormat(A)
    {
        var D = ListToArray('M,CM,D,C,XC,L,X,IX,V,IV,I');
        var I = [1000,900,500,100,90,50,10,9,5,4,1];
        var R = '';
        var x = 1;
        while ( A > 0 )
        {
            while( A >= I[x] )
            {
                R &= D[x];
                A -= I[x];
            }
            x++;
        }
        return R;
    }

    WriteOutput( RomanNumberFormat(N) );
</cfscript>
Basalt answered 27/12, 2008 at 2:21 Comment(0)
C
0

Language: Erlang, Char count: 222

EDIT2: Erlang preprocessor allows some sort of unbalanced macros so this version is 9 chars shorter.

-module(n2).
-export([y/1]).
-define(D(V,S),n(N)when N>=V->[??S|n(N-V)];).
y(N)->io:format(n(N)).
?D(1000,M)?D(900,CM)?D(500,D)?D(400,CD)?D(100,C)?D(90,XC)?D(50,L)?D(40,XL)?D(10,X)?D(9,IX)?D(5,V)?D(4,IV)?D(1,I)n(0)->[10].

EDIT: Shorter version inspired by Darius version (231 chars)

-module(n).
-export([y/1]).
y(N)->io:format([n(N),10]).
n(N)when N>9->[Y||C<-n(N div 10),{K,Y}<-lists:zip("IVXLC","XLCDM"),K==C]++o(N rem 10);n(N)->o(N).
o(N)->lists:nth(N+1,[[]|string:tokens("I II III IV V VI VII VIII IX"," ")]).

It's less readable but save 2 chars (233 chars).

-module(n).
-export([y/1]).
-define(D(V,S),n(N)when N>=V->[??S|n(N-V)]).
y(N)->io:format(n(N)).
?D(1000,M);?D(900,CM);?D(500,D);?D(400,CD);?D(100,C);?D(90,XC);?D(50,L);?D(40,XL);?D(10,X);?D(9,IX);?D(5,V);?D(4,IV);?D(1,I);n(0)->[10].

Command line version:

-module(n).
-export([y/1]).
-define(D(V,S),n(N)when N>=V->[??S|n(N-V)]).
y([N])->io:format(n(list_to_integer(N))),init:stop().
?D(1000,M);?D(900,CM);?D(500,D);?D(400,CD);?D(100,C);?D(90,XC);?D(50,L);?D(40,XL);?D(10,X);?D(9,IX);?D(5,V);?D(4,IV);?D(1,I);n(0)->[10].

Invocation:

$ erl -noshell -noinput -run n y 2009
MMIX

EDIT: I saved 17 chars using literal macro expansion.

Carvel answered 27/12, 2008 at 2:21 Comment(0)
F
0

Language: C, Char count: 195

Based heavily off of me.yahoo.com/joe_mucchielle's C solution:

char t[99],*o=t+99,*s="IVXLCDMM",*p,x;n(v){*--o=p[v];}main(int i,int**v){i=atoi(v[1]);*o=0;
for(p=s+1;*p&&i;p+=2){x=i%10;if(x%5==4)n(x==9),n(-1);else{for(;x%5;--x)n(-1);if(x)n(0);}i/=10;}puts(o);}
Foah answered 27/12, 2008 at 2:21 Comment(0)
G
0

Here is a C solution in 252 meaningful chars. Valid from 0 <= i < 4000. Mostly I wrote this because so many solutions include IV and IX at array points. Decoding it: t is our temp buffer that we back fill so that we don't have to reverse it on output. The buffer passed in must be at least 16 chars (for 3888 -> MMMDCCCLXXXVIII).

 char* i2r(int i, char* r) {
     char t[20];
     char* o=t+19;*o=0;
     char* s="IVXLCDMM";
     for (char*p=s+1;*p&&i;p+=2) {
         int x=i%10;
         if (x==9) {*--o=p[1];*--o=p[-1];}
         else if (x==4) {*--o=*p;*--o=p[-1];}
         else {
             for(;x&&x!=5;--x)*--o=p[-1];
             if(x)*--o=*p;
         }
         i/=10;
     }
     return strcpy(r,o);
 }

And I always forget to put the main on. So much for 252 chars:

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 void main(int a,char**v){
     char buf[16];
     printf("%s\n",i2r(atoi(v[1])));
 }
Golding answered 27/12, 2008 at 2:21 Comment(1)
You can in fact lose characters by using main() instead of a function. Remember you can use K&R-style C, and omit your #include's.Foah
P
0

Java: 286 significant characters

public class R {

    String[]x="M,CM,D,C,XC,L,X,IX,V,I".split(",");
    int[]n={1000,900,500,100,90,50,10,9,5,1};

    String p(String s,int d,int i){return 10<=i?s:n[i]<=d?p(s+x[i],d-n[i],i):p(s,d,i+1);}

    public static void main(String[] a) {
        System.out.println(new R().p("",Integer.parseInt(a[0]),0));
    }

}

By "significant characters", I mean the printing characters and required spaces (e.g. between type and argument), but not pure cosmetic whitespace (newlines and indentation).

Perplex answered 27/12, 2008 at 2:21 Comment(0)
Q
0

Real simple: pass the query to Google and screenscrape the answer. Next. :p

BTW, shouldn't this be a community wiki?

Quipster answered 27/12, 2008 at 2:41 Comment(3)
Yes - have changed to community mode. If you can write said screenscraper (and keep it short obviously) then go for it!Concision
It's not so simple. Google rejects queries that don't appear to come from a standard browser. Moreover, the resulting HTML is a mess. You won't be happy with regular expressions.Innis
google_roman() { lynx -dump google.com/search?q=$1+in+roman \ |awk "/^$1 = /{print \$3}"; }; google_roman 4999Cockroach
F
0

Delphi (or Pascal, there's nothing Delphi-specific here):

Function ToRoman(N : Integer) : String;

Const
    V : Array [1..13] of Word = (1000,900,500,400,100,90,50,40,10.9,5,4,1);
    T : Array [1..13] of String = ('M','CM','D','CD','C','XC','L','XL','X','IX','V','I');

Var I : Word;

Begin
    I := 1;
    Repeat
        While N < V[I] do Inc(I);
        Result := Result + T[I];
        N := N - V[I];
    Until N = 0;
End;

How is everyone getting the character counts? (I count 8 essential spaces, all the rest are simply for formatting.)

Felker answered 27/12, 2008 at 5:51 Comment(1)
Some text editors, like vi, tell you how many bytes are in the file. Or, you can use wc. No comments about what tools are available in non-Unix platforms though. :-PHungerford

© 2022 - 2024 — McMap. All rights reserved.