diff options
| -rw-r--r-- | challenge-135/bruce-gray/perl/ch-1.pl | 25 | ||||
| -rw-r--r-- | challenge-135/bruce-gray/perl/ch-2.pl | 37 | ||||
| -rw-r--r-- | challenge-135/bruce-gray/raku/ch-1.raku | 22 | ||||
| -rw-r--r-- | challenge-135/bruce-gray/raku/ch-2.raku | 33 |
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"; +} |
