Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

Convert Roman numerals to decimal

by Anonymous Monk
on Nov 14, 2002 at 10:20 UTC ( #212803=snippet: print w/replies, xml ) Need Help??
Description: This snippet converts a Roman numeral (<= 4000) to its value. It will also reject poorly-formed Roman numerals. Obviously this is a learning exersize, as I'm new to Perl. Any suggestions for improvements would be very welcome.
print "Enter a Roman numeral: ";
chomp ($_ = <STDIN>);

unless (m/^
        m{0,3}    # thousands
        (cm|dc{0,3}|cd|c{0,3})    # hundreds
        (xc|lx{0,3}|xl|x{0,3})    # tens
        (ix|vi{0,3}|iv|i{0,3})    # ones
        $/ix) {
  die "That doesn't appear to be a well-formed Roman numeral.\n";
}

$val = 0;
if (s/cm//i) {$val += 900;}
if (s/cd//i) {$val += 400;}
if (s/xc//i) {$val += 90;}
if (s/xl//i) {$val += 40;}
if (s/ix//i) {$val += 9;}
if (s/iv//i) {$val += 4;}
while (m/m/g) {$val += 1000;}
while (m/d/g) {$val += 500;}
while (m/c/g) {$val += 100;}
while (m/l/g) {$val += 50;}
while (m/x/g) {$val += 10;}
while (m/v/g) {$val += 5;}
while (m/i/g) {$val += 1;}

print "$val\n";
Replies are listed 'Best First'.
Re: Convert Roman numerals to decimal
by mirod (Canon) on Nov 14, 2002 at 12:43 UTC

    As you are new to Perl I think this is an excellent opportunity to start learning a couple of useful reflexes:

    • look at CPAN first, as already mentioned there is a Roman module, it is even reviewed on this site! So there is no need to re-invent this specific wheel.
    • use -w and use strict;, they will save you countless hours of chasing after silly bugs,
    • test your code! Get into the habit of always writing tests, write them even _before_ you start coding, then when your code passes all the test you know you are done

    So here is a test for your code that shows that... it does not pass! Note that handling IIII as 4 can be considered optional, as it is only used on clock dials:

    #!/usr/bin/perl -w use strict; while( <DATA>) { chomp; s{\s*#.*$}{}; # remove comments next unless( m{\S}); # skip empty lines my( $roman, $decimal)= split /\t/; unless( $decimal == decimal( $roman)) { warn "error $roman translated to ", decimal( $roman), " instea +d of $decimal\n"; } } sub decimal { $_= shift; # roman unless ( m/^ m{0,3} # thousands (cm|dc{0,3}|cd|c{0,3}) # hundreds (xc|lx{0,3}|xl|x{0,3}) # tens (ix|vi{0,3}|iv|i{0,3}) # ones $/ix) { die "That doesn't appear to be a well-formed Roman numeral.\n"; } my $val = 0; if (s/cm//i) {$val += 900;} if (s/cd//i) {$val += 400;} if (s/xc//i) {$val += 90;} if (s/xl//i) {$val += 40;} if (s/ix//i) {$val += 9;} if (s/iv//i) {$val += 4;} while (m/m/g) {$val += 1000;} while (m/d/g) {$val += 500;} while (m/c/g) {$val += 100;} while (m/l/g) {$val += 50;} while (m/x/g) {$val += 10;} while (m/v/g) {$val += 5;} while (m/i/g) {$val += 1;} return $val; } __DATA__ I 1 II 2 III 3 IV 4 V 5 VI 6 VII 7 VIII 8 IX 9 X 10 XI 11 XIV 14 # add more test here, V, C... MCM 1900 IIII 4 # for clocks
Re: Convert Roman numerals to decimal
by dada (Chaplain) on Nov 14, 2002 at 10:25 UTC
    take a look at the source for the Roman module by OZAWA Sakuro.

    cheers,
    Aldo

    King of Laziness, Wizard of Impatience, Lord of Hubris

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: snippet [id://212803]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (4)
As of 2022-06-29 19:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    My most frequent journeys are powered by:









    Results (97 votes). Check out past polls.

    Notices?