\$x = 'ii'; \$y = 'ii'; sub Roman { =pod This doesn't check for validity, as the subtraction rule is always honored, even for I before M if you want to do that. Roman numerals generally allow I only before V or X for the subtraction rule, X before an L or a C, and C before a D or an M. If you need to check validity, it'd be a task suitable for a separate sub since this one should be able to handle horked but workable values by design, just in case. Heck, this doesn't even check for the existence of invalid characters. It just ignores them. =cut my \$z = 0; my @foo = uc(shift) =~ /(M+|D+|C+|L+|X+|V+|I+)/g; my %value = ( 'M' => 1000, 'D' => 500, 'C' => 100, 'L' => 50, 'X' => 10, 'V' => 5, 'I' => 1, ); for ( my \$i = 0; \$i < scalar @foo; \$i++ ) { my \$ch = substr \$foo[\$i], 0, 1; my \$v = \$value{\$ch}; my \$nxt_ch = ''; my \$nxt_v = -1; if ( defined ( \$foo[\$i + 1] ) ) { \$nxt_ch = substr( \$foo[\$i + 1], 0, 1 ); \$nxt_v = \$value{\$nxt_ch}; } foreach ( 1..length \$foo[\$i] ) { if ( \$nxt_v > \$v ) { \$z -= \$value{\$ch}; } else { \$z += \$value{\$ch}; } } } return \$z; } printf "The result is: %d\n", (Roman \$x) + (Roman \$y);