aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUtil <bruce.gray@acm.org>2021-10-24 17:56:45 -0500
committerUtil <bruce.gray@acm.org>2021-10-24 17:56:45 -0500
commit5d6380cec60bdbcc83453226ecc7b71e915fbb93 (patch)
tree89729388e4aa2b85899845733a0f90caa93e8f71
parent484c41107a3c73d28fb2df5c23d2ba8d8a16a5fc (diff)
downloadperlweeklychallenge-club-5d6380cec60bdbcc83453226ecc7b71e915fbb93.tar.gz
perlweeklychallenge-club-5d6380cec60bdbcc83453226ecc7b71e915fbb93.tar.bz2
perlweeklychallenge-club-5d6380cec60bdbcc83453226ecc7b71e915fbb93.zip
Add Raku and Perl solutions for #135 by Bruce Gray
-rw-r--r--challenge-135/bruce-gray/perl/ch-1.pl25
-rw-r--r--challenge-135/bruce-gray/perl/ch-2.pl37
-rw-r--r--challenge-135/bruce-gray/raku/ch-1.raku22
-rw-r--r--challenge-135/bruce-gray/raku/ch-2.raku33
4 files changed, 117 insertions, 0 deletions
diff --git a/challenge-135/bruce-gray/perl/ch-1.pl b/challenge-135/bruce-gray/perl/ch-1.pl
new file mode 100644
index 0000000000..1d25bddda6
--- /dev/null
+++ b/challenge-135/bruce-gray/perl/ch-1.pl
@@ -0,0 +1,25 @@
+use Modern::Perl;
+use Test::More;
+
+my @tests = (
+ [ 1234567, 345 ],
+ [ -123, 123 ],
+ [ 1, 'too short' ],
+ [ 10, 'even number of digits' ],
+);
+plan tests => 0+@tests;
+
+sub middle_three_digits {
+ die if @_ != 1;
+ my $a = abs shift;
+ my $l = length $a;
+ return 'even number of digits' if $l % 2 == 0;
+ return 'too short' if $l < 3;
+ return substr $a, ($l - 3) / 2, 3;
+}
+
+for (@tests) {
+ my ( $input, $expected ) = @{$_};
+ my $got = middle_three_digits($input);
+ is $got, $expected, "middle_three_digits($input)";
+}
diff --git a/challenge-135/bruce-gray/perl/ch-2.pl b/challenge-135/bruce-gray/perl/ch-2.pl
new file mode 100644
index 0000000000..16eecaebf4
--- /dev/null
+++ b/challenge-135/bruce-gray/perl/ch-2.pl
@@ -0,0 +1,37 @@
+use Modern::Perl;
+use List::Util qw<sum>;
+use Test::More;
+
+my @tests = (
+ [ '2936921' => 1 ],
+ [ '1234567' => 0 ],
+ [ 'B0YBKL9' => 1 ],
+);
+plan tests => 0+@tests;
+
+# Based on my original code from RosettaCode.
+BEGIN {
+ my $c = 0;
+ my %base36 = map { $_ => $c++ } 0..9, 'A'..'Z';
+ my @weights = ( 1, 3, 1, 7, 3, 9 );
+ sub sedol {
+ die if @_ != 1;
+ my ($s) = @_;
+
+ my @vs = @base36{ split '', $s };
+ die if grep { not defined } @vs;
+ my $checksum = sum map { $vs[$_] * $weights[$_] } keys @vs;
+ return $s . ((10 - $checksum % 10) % 10);
+ }
+}
+sub valid_sedol {
+ die if @_ != 1;
+ my ($s) = @_;
+ return 0+( $s eq sedol( substr($s,0,-1) ) );
+}
+
+for (@tests) {
+ my ( $input, $expected ) = @{$_};
+ my $got = valid_sedol($input);
+ is $got, $expected, "valid_sedol('$input') == $expected";
+}
diff --git a/challenge-135/bruce-gray/raku/ch-1.raku b/challenge-135/bruce-gray/raku/ch-1.raku
new file mode 100644
index 0000000000..19ae6de6a6
--- /dev/null
+++ b/challenge-135/bruce-gray/raku/ch-1.raku
@@ -0,0 +1,22 @@
+use Test;
+
+my @tests =
+ 1234567 => 345,
+ -123 => 123,
+ 1 => 'too short',
+ 10 => 'even number of digits',
+;
+plan +@tests;
+
+sub middle_three_digits ( Int $n --> Int ) {
+ my $a = $n.abs;
+ fail 'even number of digits' if $a.chars %% 2;
+ fail 'too short' if $a.chars < 3;
+ return + $a.substr( ($a.chars - 3) / 2, 3 );
+}
+
+for @tests -> ( :key($input), :value($expected) ) {
+ my $got = middle_three_digits($input);
+ $got //= $got.exception.payload; # Turn a Failure into a Str
+ is $got, $expected, "middle_three_digits($input)";
+}
diff --git a/challenge-135/bruce-gray/raku/ch-2.raku b/challenge-135/bruce-gray/raku/ch-2.raku
new file mode 100644
index 0000000000..e12db01166
--- /dev/null
+++ b/challenge-135/bruce-gray/raku/ch-2.raku
@@ -0,0 +1,33 @@
+use Test;
+my @tests =
+ '2936921' => 1,
+ '1234567' => 0,
+ 'B0YBKL9' => 1,
+;
+plan +@tests;
+
+# Based on my original code from RosettaCode.
+sub sedol ( Str $s --> Str ) {
+ die 'No vowels allowed' if $s ~~ /<[AEIOU]>/;
+ die 'Invalid format' if $s !~~ / ^ <[0..9A..Z] - [AEIOU]>**6 $ /;
+
+ constant %base36 = ( |(0..9), |('A'..'Z') ) Z=> ^36;
+ constant @weights = 1, 3, 1, 7, 3, 9;
+
+ my @vs = $s.comb.map: {
+ %base36{$_}
+ orelse fail "Bad digit '$_'"
+ };
+
+ my $checksum = [+] @vs Z* @weights;
+ return $s ~ (10 - $checksum % 10) % 10;
+}
+
+sub valid_sedol ( Str $s --> Int ) {
+ return + ( $s eq $s.substr(0, *-1).&sedol );
+}
+
+for @tests -> ( :key($input), :value($expected) ) {
+ my $got = valid_sedol($input);
+ is $got, $expected, "valid_sedol('$input') == $expected";
+}