#!/usr/bin/perl # # Converts Roman numerals to arabic numerals # # Supports iv, ix, xl, xc, cd, cm convention # Supports iiii, xxxx, convention # Does NOT support ic, im, xm, convention # # written 27/6/00 sub arabise { $roman = $_[0]; # delete any carriage returns if ($roman =~ /\n/) { $roman =~ s/[\n]//g; } # lower case letters if ($roman =~ /[A-Z]/) { $roman =~ tr/[A-Z]/[a-z]/; } # report dodgy roman numerals if ($roman =~ /i[ldcm]|v[vxldcm]|x[dm]|l[lcdm]|d[dm]/ || $roman =~ /[iv]+ix|[iv]+iv|ix[xivcdlm]|xl[xcdml]|xc[cxmd]|cm[mdc]/ || $roman =~ /iiiii|xxxxx|ccccc/) { print STDERR "\n\tWarning \"$roman\" not a valid Roman numeral.\n"; print STDERR "\tThis will probably cause an erroneous output.\n\n"; } $units = 0; $tens = 0; $hundreds = 0; $thousands = 0; $i_counter = 0; $x_counter = 0; $c_counter = 0; $m_counter = 0; if ($roman =~ /[ixv]/) { $units = $roman; $units =~ s/xl//; $units =~ s/xc//; $units =~ s/[mdcl]//; $units =~ s/^[x]+//; # units if ($units =~ /iv$/) { $units = 4; } elsif ($units =~ /ix$/) { $units = 9; } elsif ($units =~ /v$/) { $units = 5; } elsif ($units =~ /[i]$/) { $temp_units = $units; while ($temp_units =~ s/i//) { $i_counter++; } if ($units =~ /v/) { $units = $i_counter + 5; } else { $units = $i_counter; } $i_counter = 0; } else { $units = 0; } } # tens if ($roman =~ /[xl]/) { $tens = $roman; $tens =~ s/[md]+//; $tens =~ s/iv$//; $tens =~ s/ix$//; $tens =~ s/v[i]+$//; $tens =~ s/[i]+$//; $tens =~ s/^[c]+//; $temp_tens = $tens; while ($temp_tens =~ s/x//) { $x_counter++; } if ($tens =~ /l/) { if ($tens =~ /xl/) { $tens = 4; } elsif ($tens =~ /lx/) { $tens = 5 + $x_counter; } else { $tens = 5; } } elsif ($tens =~ /xc/) { $tens = 9; } else { $tens = $x_counter; } } # hundreds if ($roman =~ /[cd]/) { $hundreds = $roman; if ($hundreds =~ /^xc/) { $hundreds = 0; } elsif ($hundreds =~ /c/) { $hundreds =~ s/xc//; $hundreds =~ s/[xvil]+//; $temp_hundreds = $hundreds; while ($temp_hundreds =~ s/c//) { $c_counter++; } if ($hundreds =~ /d/) { if ($hundreds =~ /cd/) { $hundreds = 4; } else { $hundreds = 5 + $c_counter; } } elsif ($hundreds =~ /cm/) { $hundreds = 9; } else { $hundreds = $c_counter; } } else { $hundreds = 5; } } # thousands if ($roman =~ /m/) { $thousands = $roman; if ($thousands =~ /^cm/) { $thousands = 0; } elsif ($thousands =~ /m/) { $thousands =~ s/cm//; $temp_thousands = $thousands; while ($temp_thousands =~ s/m//) { $m_counter++; } $thousands = $m_counter; } } $arabic_number = $thousands . $hundreds . $tens . $units; return $arabic_number; } 1; # returns true (a perl requirement)