-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathDicRoman.pm
73 lines (66 loc) · 1.7 KB
/
DicRoman.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/usr/bin/perl
package DicRoman;
use warnings;
use strict;
use Exporter;
our @ISA = ('Exporter');
our @EXPORT = (
'isroman',
'arabic',
'Roman',
'roman',
'sortroman',
);
# Localized Roman Package, because LCL uses lxxxx, which is strictly speaking not a roman number.
#Begin
our %roman2arabic = qw(I 1 V 5 X 10 L 50 C 100 D 500 M 1000);
our %roman_digit = qw(1 IV 10 XL 100 CD 1000 MMMMMM);
our @figure = reverse sort keys %roman_digit;
$roman_digit{$_} = [split(//, $roman_digit{$_}, 2)] foreach @figure;
sub isroman{
my $String= shift;
if( defined $String and $String=~m/^[ivxlcm]+$/ ){ return(1); }
else{ return(0); }
}
sub arabic{
my $arg = shift;
isroman $arg or return undef;
my($last_digit) = 1000;
my($arabic);
foreach (split(//, uc $arg)) {
my($digit) = $roman2arabic{$_};
$arabic -= 2 * $last_digit if $last_digit < $digit;
$arabic += ($last_digit = $digit);
}
$arabic;
}
sub Roman{
my $arg = shift;
0 < $arg and $arg < 4000 or return undef;
my($x, $roman);
foreach (@figure) {
my($digit, $i, $v) = (int($arg / $_), @{$roman_digit{$_}});
if (1 <= $digit and $digit <= 3) {
$roman .= $i x $digit;
} elsif ($digit == 4) {
$roman .= "$i$v";
} elsif ($digit == 5) {
$roman .= $v;
} elsif (6 <= $digit and $digit <= 8) {
$roman .= $v . $i x ($digit - 5);
} elsif ($digit == 9) {
$roman .= "$i$x";
}
$arg -= $digit * $_;
$x = $i;
}
$roman;
}
sub roman{
lc Roman shift;
}
sub sortroman{
return ( sort {arabic($a) <=> arabic($b)} @_ );
}
#End Localized Roman Package
1;