my %from_roman = ( I => 1, V => 5, X => 10, L => 50, C => 100, D => 500, M => 1000, ); sub from_roman (_) { my ($roman) = @_; my $n = 0; while ($roman =~ s/(I[VXLCDM]|X[LCDM]|C[DM])//) { my ($minus, $plus) = split //, $1; $n += $from_roman{$plus} - $from_roman{$minus}; } $n += $from_roman{$_} for split //, $roman; $n }