I just had to do the complementary function to the snippet first presented in this node.
sub inc { my $str = uc shift; $str =~ s/XLVIII$/IL/ or $str =~ s/VIII$/IX/ or $str =~ s/III$/IV/ or $str =~ s/DCCCXCIX$/CM/ or $str =~ s/CCCXCIX$/CD/ or $str =~ s/LXXXIX$/XC/ or $str =~ s/XXXIX$/XL/ or $str =~ s/(I{1,2})$/$1I/ or $str =~ s/CDXCIX$/D/ or $str =~ s/CMXCIX$/M/ or $str =~ s/XCIX$/C/ or $str =~ s/I([VXLCDM])$/$1/ or $str =~ s/([VXLCDM])$/$1I/; return $str; } sub dec { my $str = uc shift; $str =~ s/IL$/XLVIII/ or $str =~ s/IX$/VIII/ or $str =~ s/IV$/III/ or $str =~ s/CM$/DCCCXCIX/ or $str =~ s/CD$/CCCXCIX/ or $str =~ s/XC$/LXXXIX/ or $str =~ s/XL$/XXXIX/ or $str =~ s/III$/II/ or $str =~ s/II$/I/ or $str =~ s/([VXLCDM])I$/$1/ or $str =~ s/([VXL])$/I$1/ or $str =~ s/D$/CDXCIX/ or $str =~ s/M$/CMXCIX/ or $str =~ s/C$/XCIX/; return $str; }

Replies are listed 'Best First'.
Re: symbolic increment/decrement of roman numerals
by kaif (Friar) on Jun 03, 2005 at 22:47 UTC
    Great. My only question is why is 49 translated to IL (and vice versa)? According to the rules I know, along with those of Math::Roman and Roman, this is illegal. And if it were legal, shouldn't IC, ID, and IM be legal, too?

    Note: I understand the idea of the symbolic approach, so that such things as inc('IM') return M (so, in this sense, IM is "legal" input, but not the expected output for dec('M') --- this is what I mean by "legal"). I just thought that inc('IL') should return L as expected, but dec('L') should return XLIX. (Note, similarly, that decrementing D ten times returns CDXC and not XD.)

      Indeed, for decrement the snippet has wrong behaviour for these cases. It can be fixed by extending the regex ruleset slightly, which is left as an exercise to the reader.

      Clearly, if the snippet would behave correcting, i.e. dec('IL') should return XLVIII, this would require more "gist".

      Basically I tested the inc/dec subs by letting the one increment and the other decrement numbers and checked whether the result remained original. Like so:

      use strict; my $roman = 'I'; my $roman2; while(1) { $roman = &inc($roman); # print "$roman\n"; if($roman ne &dec(&inc($roman))) { print "MISMATCH for $roman\n"; print "\t",&inc($roman),"\n"; print "\t",&dec($roman),"\n"; } }

      Bye
       PetaMem
          All Perl:   MT, NLP, NLU

        Clearly, if the snippet would behave correcting, i.e. dec('IL') should return XLVIII, this would require more "gist".
        Actually, I applaud you in the fact that dec('IL') does return XLVIII.
Re: symbolic increment/decrement of roman numerals
by DrHyde (Prior) on May 24, 2005 at 11:52 UTC
      Sure. Exactly as this 3 year old comment in the original thread. Therefore see the reply to it there.

      Bye
       PetaMem
          All Perl:   MT, NLP, NLU