aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xchallenge-010/e-choroba/perl5/ch-1a.pl37
-rw-r--r--challenge-047/e-choroba/perl/MyRoman.pm56
-rwxr-xr-xchallenge-047/e-choroba/perl/ch-1.pl16
-rwxr-xr-xchallenge-047/e-choroba/perl/ch-2.pl15
4 files changed, 124 insertions, 0 deletions
diff --git a/challenge-010/e-choroba/perl5/ch-1a.pl b/challenge-010/e-choroba/perl5/ch-1a.pl
new file mode 100755
index 0000000000..9f64ce21b5
--- /dev/null
+++ b/challenge-010/e-choroba/perl5/ch-1a.pl
@@ -0,0 +1,37 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+
+use lib '../../../challenge-047/e-choroba/perl';
+use MyRoman qw{ to_roman from_roman };
+
+use Test::More;
+
+my %test = (XXXIX => 39,
+ CCXLVI => 246,
+ DCCLXXXIX => 789,
+ MMCDXXI => 2421,
+ CLX => 160,
+ CCVII => 207,
+ MIX => 1009,
+ MLXVI => 1066,
+ MDCCLXXVI => 1776,
+ MCMIII => 1903, # MDCDIII
+ MCMX => 1910,
+ MCMLIV => 1954,
+ MCMXCIX => 1999, # MIM
+ MMXIX => 2019,
+ MMMCMXCIX => 3_999);
+
+for my $roman (keys %test) {
+ is from_roman($roman), $test{$roman};
+}
+
+for my $roman (keys %test) {
+ is to_roman($test{$roman}), $roman;
+}
+
+is from_roman('MIM'), 1999;
+is from_roman('MDCDIII'), 1903;
+
+done_testing();
diff --git a/challenge-047/e-choroba/perl/MyRoman.pm b/challenge-047/e-choroba/perl/MyRoman.pm
new file mode 100644
index 0000000000..4d8a5e1120
--- /dev/null
+++ b/challenge-047/e-choroba/perl/MyRoman.pm
@@ -0,0 +1,56 @@
+package MyRoman;
+
+use Exporter qw{ import };
+our @EXPORT_OK = qw{ from_roman to_roman };
+
+use warnings;
+use strict;
+
+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;
+ return $n
+}
+
+my %to_roman = reverse %from_roman;
+my %subtractive = (
+ 'IIII' => 'IV',
+ 'VIIII' => 'IX',
+ 'XXXX' => 'XL',
+ 'LXXXX' => 'XC',
+ 'CCCC' => 'CD',
+ 'DCCCC' => 'CM',
+);
+my $subtractive_re = join '|',
+ sort { length $b <=> length $a }
+ keys %subtractive;
+sub to_roman {
+ my ($n) = @_;
+ my $roman = "";
+ while ($n) {
+ for my $i (sort { $b <=> $a } keys %to_roman) {
+ while ($n >= $i) {
+ $n -= $i;
+ $roman .= $to_roman{$i};
+ }
+ }
+ }
+ $roman =~ s/($subtractive_re)/$subtractive{$1}/g;
+ return $roman
+}
+
+__PACKAGE__
diff --git a/challenge-047/e-choroba/perl/ch-1.pl b/challenge-047/e-choroba/perl/ch-1.pl
new file mode 100755
index 0000000000..5e92e98fed
--- /dev/null
+++ b/challenge-047/e-choroba/perl/ch-1.pl
@@ -0,0 +1,16 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use feature qw{ say };
+
+use lib '.';
+use MyRoman qw{ to_roman from_roman }; # Extracted from PWC010/1.
+
+my ($n1, $op, $n2) = @ARGV;
+my $function = { '+' => sub { $_[0] + $_[1] },
+ '-' => sub { $_[0] - $_[1] },
+ '*' => sub { $_[0] * $_[1] },
+ '/' => sub { int($_[0] / $_[1]) }
+ }->{$op}
+ or die "Unknown operator $op.";
+say to_roman($function->(map from_roman($_), $n1, $n2));
diff --git a/challenge-047/e-choroba/perl/ch-2.pl b/challenge-047/e-choroba/perl/ch-2.pl
new file mode 100755
index 0000000000..e8573a7470
--- /dev/null
+++ b/challenge-047/e-choroba/perl/ch-2.pl
@@ -0,0 +1,15 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use feature qw{ say };
+
+sub gapful_iterator {
+ my ($n) = @_;
+ my $iterator = sub {
+ $n++ until 0 == $n % join "", $n =~ /^(.)/, $n=~ /(.)$/;
+ $n++
+ };
+}
+
+my $iter = gapful_iterator(100);
+say $iter->() for 1 .. 20;