home *** CD-ROM | disk | FTP | other *** search
- Xref: sparky comp.lang.perl:5736 sci.classics:683
- Path: sparky!uunet!ogicse!uwm.edu!rutgers!psinntp!psinntp!avernus!mgfrank
- From: mgfrank@avernus.com (Marc G. Frank)
- Newsgroups: comp.lang.perl,sci.classics
- Subject: SCRIPT: Roman numeral conversion
- Message-ID: <1992Sep3.002639.8834@avernus.com>
- Date: 3 Sep 92 00:26:39 GMT
- Article-I.D.: avernus.1992Sep3.002639.8834
- Organization: Maryland Appreciation Society
- Lines: 187
-
-
- How many times have you said:
-
- "Gee, perl looks pretty neat. Too bad it doesn't handle Roman numerals."
-
- or:
-
- "DAMN! If perl's such a great language, then why the hell can't it use
- Roman numerals?"
-
- or:
-
- "I'd like to recommend perl, sir, but I'm afraid I can't until the Roman
- numeral matter is resolved."
-
- or:
-
- "I'd send Larry lots and lots of money for writing such a useful
- utility, but I won't because it doesn't do Roman numerals."
-
- vel:
-
- "Stercus! Cur non margarita potest numeros Romanos computare?'
-
- Hundreds if not thousands of times, I reckon. Well, relax, because
- the wait is over! Included below is a package to convert to and from
- Roman numerals.
-
- While ator, the routine to convert to Roman numerals, could be
- marginally useful on occasion (page numbers, perhaps), as far as I can
- tell rtoa, which converts from Roman numerals, is useless unless you
- want to use it to cheat on^H^H^H^H^H^H^H^Hcheck your Latin I homework.
- I pretty much just wrote that one for the fun of it. Note that this
- package hasn't been thoroughly tested (it converts the numbers I need it
- to convert, so hey, why test further?), so you might not want to use it
- for mission-critical applications. If you *have* a mission-critical
- application that needs Roman numeral conversion, then perhaps it's time
- to *seriously* reconsider your mission. :-)
-
- Also included is testromn.pl. Feed it either Arabic or Roman numerals
- on stdin, and it spits out the other on stdout. Rather useful for
- checking Latin I homework. Other documentation is to found in the
- comments in roman.pl.
-
- Enjoy. BTW, this article is crossposted(!), so if you follow up be sure
- to edit the Newsgroups: line accordingly.
-
-
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | Marc G. Frank mgfrank@avernus.com |
- | I'd rather be in Eldersburg. |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-
- # This is a shell archive. Save it in a file, remove anything before
- # this line, and then unpack it by entering "sh file". Note, it may
- # create directories; files and directories will be owned by you and
- # have default permissions.
- #
- # This archive contains:
- #
- # roman.pl
- # testromn.pl
- #
- echo x - roman.pl
- sed 's/^X//' >roman.pl << 'END-of-roman.pl'
- X#
- X# roman.pl -- package to convert to and from Roman numerals
- X#
- X# Marc G. Frank
- X# mgfrank@avernus.com
- X# Written August , 992
- X# Author got around to documenting it September 2, 992
- X#
- X# This amazingly useful package makes a modest attempt to convert between
- X# Roman and Arabic numerals. It will convert Arabic integers to Roman
- X# numerals in the range <= x <= 4999, after which things get a bit messy:
- X# the Roman numerals have to have bars over them (or something like that)
- X# which isn't easily representable in ASCII. If you feed ator something
- X# that isn't an integer in this range it returns ''.
- X#
- X# Converting the other way around is a bit trickier as far as error
- X# detection is concerned, so rtoa doesn't do much of it. Suffice it to
- X# say that if you feed it a valid Roman numeral you'll get the Arabic
- X# equivalent back. If you feed it something that obviously isn't a
- X# Roman numeral it returns ''. If you feed it an invalid Roman numeral
- X# (like XXCMDLM) you'll get something back, but if the input isn't valid
- X# there's no reason the output should be. :-)
- X#
- X# Usage:
- X# require "roman.pl";
- X# $something = &ator($some_number);
- X# $something_else = &rtoa($some_roman_numeral);
- X#
- X# Note that Roman numerals are returned in uppercase. If you don't like this,
- X# use tr on the resulting string.
- X#
- X# Bugs to mgfrank@avernus.com
- X
- X
- Xpackage roman;
- X
- X
- Xsub main'ator { # Convert Arabic integers to Roman numerals
- X local($n) = @_;
- X local($i, $roman);
- X return '' if ($n =~ /[\D.Ee]/ || $n < || $n > 4999); # Rudimentary error-
- X local(@numerals) = (I,X,C,M); # checking
- X
- X # I'm bad at math so I found it easier to do the conversion stringly. This
- X # bit converts the Arabic numeral in each position to the corresponding
- X # number of equivalent Roman numerals. That is, if the number to be
- X # converted is 992, the 9 in the hundreds place is converted to CCCCCCCCC.
- X
- X $n = reverse($n);
- X for($i = length($n) - ; $i >= 0 ; $i--) {
- X $roman .= @numerals[$i] x substr($n, $i, );
- X }
- X
- X # Once that's been done, all that's left to do is convert strings like
- X # CCCCCCCCC to strings like XC.
- X
- X $roman =~ s/C{9}/CM/;
- X $roman =~ s/C{5}/D/;
- X $roman =~ s/C{4}/CD/;
- X $roman =~ s/X{5}/L/;
- X $roman =~ s/X{4}/XL/;
- X $roman =~ s/LXL/XC/;
- X $roman =~ s/I{9}/IX/;
- X $roman =~ s/I{5}/V/;
- X $roman =~ s/I{4}/IV/;
- X $roman;
- X}
- X
- X
- X
- Xsub main'rtoa { # Convert Roman numerals into Arabic
- X local($n) = @_;
- X $n =~ tr/mdclxvi/MDCLXVI/; # Canonicalize to uppercase
- X return '' if $n =~ /[^MDCLXVI]/; # *Very* rudimentary error-checking
- X local($arabic, $i);
- X local(%numerals) = ('M', 000,
- X 'D', 500,
- X 'C', 00,
- X 'L', 50,
- X 'X', 0,
- X 'V', 5,
- X 'I', );
- X
- X # Do the reverse of before. Translate strings like XC to strings like
- X # CCCCCCCCC.
- X
- X $n =~ s/CM/CCCCCCCCC/;
- X $n =~ s/CD/CCCC/;
- X $n =~ s/XL/XXXX/;
- X $n =~ s/XC/XXXXXXXXX/;
- X $n =~ s/IX/IIIIIIIII/;
- X $n =~ s/IV/IIII/;
- X
- X # Now just add the value of every character in the string to the result.
- X
- X for($i = 0 ; $i < length($n) ; $i++) {
- X $arabic += $numerals{substr($n, $i, )};
- X }
- X $arabic;
- X}
- X
- X; # Return an end-of-package true.
- END-of-roman.pl
- echo x - testromn.pl
- sed 's/^X//' >testromn.pl << 'END-of-testromn.pl'
- X#!/usr/bin/perl
- X
- Xrequire "roman.pl";
- X
- Xwhile(<STDIN>) {
- X chop;
- X if(/\d+/) { print &ator($_), "\n"; }
- X else { print &rtoa($_), "\n"; }
- X}
- END-of-testromn.pl
- exit
-
-
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
- | Marc G. Frank mgfrank@avernus.com |
- | I'd rather be in Eldersburg. |
- +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
-