# rtoa-pgatram.pl # Example run: perl rtoa-pgatram.pl t1.txt >pgatram.tmp # # Convert a "modern" Roman Numeral to its arabic (decimal) equivalent. # The alpabetic input string may be assumed to always contain a valid Roman Numeral in the range 1-3999. # Roman numerals may be upper or lower case. # Error handling is not required. # For example: # input "XLII" should produce the arabic (decimal) value 42 # input "mi" should produce the arabic (decimal) value 1001 use 5.010; # Needed for state use strict; use warnings; use List::Util qw(reduce); sub read_input_files { my $files = shift; # in: reference to a list of files containing Roman Numerals (one per line) my @list_ret; # out: reference to a list of the Roman Numerals in the files for my $fname ( @{$files} ) { open( my $fh, '<', $fname ) or die "error: open '$fname': $!"; while (<$fh>) { chomp; push @list_ret, uc($_); } close($fh) or die "error: close '$fname': $!"; } return \@list_ret; } # Function roman_to_arabic # Input: reference to a list of valid Roman Numerals in the range 1..3999 # Output: reference to a list of their arabic (decimal) values sub roman_to_arabic { my $list_in = shift; # in: reference to a list of valid Roman Numerals my @list_ret; # out: a list of their integer values state %rtoa = ( M=>1000, D=>500, C=>100, L=>50, X=>10, V=>5, I=>1 ); for (@{$list_in}) { push @list_ret, reduce { $a+$b-$a%$b*2 } map { $rtoa{$_} } split//, uc($_); } return \@list_ret; } @ARGV or die "usage: $0 file...\n"; my @rtoa_files = @ARGV; warn "rtoa pgatram start\n"; my $tstart1 = time; my $aref1 = read_input_files( \@rtoa_files ); my $tend1 = time; my $taken1 = $tend1 - $tstart1; warn "read_input_files : $taken1 secs\n"; my $tstart2 = time; my $aref2 = roman_to_arabic($aref1); my $tend2 = time; my $taken2 = $tend2 - $tstart2; warn "roman_to_arabic : $taken2 secs\n"; my $tstart3 = time; for my $n ( @{$aref2} ) { print "$n\n" } my $tend3 = time; my $taken3 = $tend3 - $tstart3; my $taken = $taken1 + $taken2 + $taken3; warn "output : $taken3 secs\n"; warn "total : $taken secs\n";