From 0b86f89009795ee7606421f61ad9bed82d45b0d7 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Mon, 25 Jan 2021 08:58:44 +0000 Subject: challenge 97 --- challenge-097/james-smith/perl/ch-1.pl | 17 +++++++++++++++++ challenge-097/james-smith/perl/ch-2.pl | 29 +++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 challenge-097/james-smith/perl/ch-1.pl create mode 100644 challenge-097/james-smith/perl/ch-2.pl diff --git a/challenge-097/james-smith/perl/ch-1.pl b/challenge-097/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..d6dfd58a56 --- /dev/null +++ b/challenge-097/james-smith/perl/ch-1.pl @@ -0,0 +1,17 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( caesar('ABCDEFGHIJKLMNOPQRSTUVWXYZ',3), 'XYZABCDEFGHIJKLMNOPQRSTUVW' ); +is( caesar('THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG',3), 'QEB NRFZH YOLTK CLU GRJMP LSBO QEB IXWV ALD' ); + +done_testing(); + +sub caesar { + return join q(), map { m{[A-Z]} ? chr 65+(ord($_)-65-$_[1])%26 : $_ } split m{}, $_[0]; +} + diff --git a/challenge-097/james-smith/perl/ch-2.pl b/challenge-097/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..26bdfe22a1 --- /dev/null +++ b/challenge-097/james-smith/perl/ch-2.pl @@ -0,0 +1,29 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( min_flips('101100101',3), 1 ); +is( min_flips('10110111', 4), 2 ); +is( min_flips('101100100',4), 1 ); +is( min_flips('0000000100100011010001010110011110001001101010111100110111101111',4), 32 ); + +done_testing(); + +sub min_flips { + my( $str, $n, @parts ) = @_;; + my $min = length $str; + push @parts, substr $str,0,$n,'' while length $str; + foreach my $r (@parts) { + my $t = 0; + foreach my $s (@parts) { + $t += ($s^$r) =~ tr/\x01/\x01/; + } + $min = $t if $t < $min; + } + return $min; +} + -- cgit From c4a60d0ec86e18c9ec046f7f341b41bb747e61fd Mon Sep 17 00:00:00 2001 From: drbaggy Date: Mon, 25 Jan 2021 14:50:16 +0000 Subject: remove the for loops and make this a map list.... --- challenge-097/james-smith/perl/ch-2.pl | 50 ++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/challenge-097/james-smith/perl/ch-2.pl b/challenge-097/james-smith/perl/ch-2.pl index 26bdfe22a1..9df291a034 100644 --- a/challenge-097/james-smith/perl/ch-2.pl +++ b/challenge-097/james-smith/perl/ch-2.pl @@ -8,22 +8,48 @@ use Test::More; is( min_flips('101100101',3), 1 ); is( min_flips('10110111', 4), 2 ); -is( min_flips('101100100',4), 1 ); +is( min_flips('101100100',3), 1 ); is( min_flips('0000000100100011010001010110011110001001101010111100110111101111',4), 32 ); +use Data::Dumper; + done_testing(); sub min_flips { - my( $str, $n, @parts ) = @_;; - my $min = length $str; - push @parts, substr $str,0,$n,'' while length $str; - foreach my $r (@parts) { - my $t = 0; - foreach my $s (@parts) { - $t += ($s^$r) =~ tr/\x01/\x01/; - } - $min = $t if $t < $min; - } - return $min; + ## Golf mode on... + return [ + map { local $/ = + local $\ = ( $_[0] ^ ( substr $_[0], $_, $_[1]) x (length($_[0])/$_[1]) ) =~ tr/\x01/\x01/, + !$_ || $_ < $/ ? $\ : $/, + } + map { $_*$_[1] } + 0 .. (length($_[0])/$_[1]-1) + ]->[-1]; + ## We could use variales here - but playing with localised special variables is fun! + ## $/ <- minimum value + ## $\ <- value for given chunk.... + ## + ## The inner map + range combination returns a list of ids of the form 0, $n, 2*$n until the + ## end of the array, we use this to chunk the array up for comparison + ## + ## Inside the end map - we first string "xor" the string with the repeated chunk of the array. + ## so e.g. for the first example this becomes: + ## '101100101' ^ '101'.'101'.'101' + ## '101100101' ^ '100'.'100'.'100' + ## '101100101' ^ '101'.'101'.'101' + ## if the symbols match you get a value \x00, when they don't match you get value \x01 + ## so we then count the \x01's using tr... and store in $\ + ## + ## Next if it is the first chunk OR the value of $\ is less than the current min ($/) + ## We set $/ to $\ otherwise we leave it as $/ + ## + ## The resultant array consists of the running minimum in the examples + ## for ex 1: it is [1,1,1] + ## for ex 2: it is [1,1] + ## for ex 3: it is [2,1,1] + ## + ## We need the last value of this so we wrap the list into an array ref and take the last element + ## + ## [ list... ]->[-1]; } -- cgit From 071408de692b446843bdc102d5b71acea69cfc92 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Mon, 25 Jan 2021 15:24:12 +0000 Subject: golfed --- challenge-097/james-smith/perl/ch-2.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/challenge-097/james-smith/perl/ch-2.pl b/challenge-097/james-smith/perl/ch-2.pl index 9df291a034..a995d64d5c 100644 --- a/challenge-097/james-smith/perl/ch-2.pl +++ b/challenge-097/james-smith/perl/ch-2.pl @@ -23,7 +23,7 @@ sub min_flips { !$_ || $_ < $/ ? $\ : $/, } map { $_*$_[1] } - 0 .. (length($_[0])/$_[1]-1) + 0 .. ( length($_[0])/$_[1] - 1 ) ]->[-1]; ## We could use variales here - but playing with localised special variables is fun! ## $/ <- minimum value -- cgit From 87f2cca1c08b724332092b0ab73fcd522247af53 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Mon, 25 Jan 2021 15:36:23 +0000 Subject: added some comments --- challenge-097/james-smith/perl/ch-2.pl | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/challenge-097/james-smith/perl/ch-2.pl b/challenge-097/james-smith/perl/ch-2.pl index a995d64d5c..805b834d72 100644 --- a/challenge-097/james-smith/perl/ch-2.pl +++ b/challenge-097/james-smith/perl/ch-2.pl @@ -17,11 +17,19 @@ done_testing(); sub min_flips { ## Golf mode on... + ## + ## This was to use this to serve as an example of perl idioms that other programmers + ## may find it difficult to understand - and so I tried to put as many of them in relatively + ## short function.... + ## + ## One statement functions are a lovely perl concept - even if they can get a bit difficult + ## to read.... + ## return [ map { local $/ = - local $\ = ( $_[0] ^ ( substr $_[0], $_, $_[1]) x (length($_[0])/$_[1]) ) =~ tr/\x01/\x01/, - !$_ || $_ < $/ ? $\ : $/, - } + local $\ = ( $_[0] ^ ( substr $_[0], $_, $_[1]) x (length($_[0])/$_[1]) ) =~ tr/\x01/\x01/, + !$_ || $_ < $/ ? $\ : $/, + } map { $_*$_[1] } 0 .. ( length($_[0])/$_[1] - 1 ) ]->[-1]; -- cgit From 79dc1dd47f6301db6742e3c1cc63f9a129ad9137 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Mon, 25 Jan 2021 15:36:37 +0000 Subject: added some comments --- challenge-097/james-smith/perl/ch-2.pl | 2 -- 1 file changed, 2 deletions(-) diff --git a/challenge-097/james-smith/perl/ch-2.pl b/challenge-097/james-smith/perl/ch-2.pl index 805b834d72..42b107ffb7 100644 --- a/challenge-097/james-smith/perl/ch-2.pl +++ b/challenge-097/james-smith/perl/ch-2.pl @@ -11,8 +11,6 @@ is( min_flips('10110111', 4), 2 ); is( min_flips('101100100',3), 1 ); is( min_flips('0000000100100011010001010110011110001001101010111100110111101111',4), 32 ); -use Data::Dumper; - done_testing(); sub min_flips { -- cgit From c0afb079eb7a7b59ee64caedef57208c63d25777 Mon Sep 17 00:00:00 2001 From: drbaggy Date: Mon, 25 Jan 2021 16:22:15 +0000 Subject: tidied up --- challenge-097/james-smith/perl/ch-2.pl | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/challenge-097/james-smith/perl/ch-2.pl b/challenge-097/james-smith/perl/ch-2.pl index 42b107ffb7..81f89d7e4f 100644 --- a/challenge-097/james-smith/perl/ch-2.pl +++ b/challenge-097/james-smith/perl/ch-2.pl @@ -6,9 +6,11 @@ use warnings; use feature qw(say); use Test::More; +is( min_flips('101101',3), 0 ); is( min_flips('101100101',3), 1 ); is( min_flips('10110111', 4), 2 ); -is( min_flips('101100100',3), 1 ); +is( min_flips('100101100',3), 1 ); +is( min_flips('101100100100101',3), 2 ); is( min_flips('0000000100100011010001010110011110001001101010111100110111101111',4), 32 ); done_testing(); @@ -23,10 +25,12 @@ sub min_flips { ## One statement functions are a lovely perl concept - even if they can get a bit difficult ## to read.... ## + + local $/; return [ - map { local $/ = - local $\ = ( $_[0] ^ ( substr $_[0], $_, $_[1]) x (length($_[0])/$_[1]) ) =~ tr/\x01/\x01/, - !$_ || $_ < $/ ? $\ : $/, + map { + local $\ = ( $_[0] ^ (substr$_[0],$_,$_[1]) x (length($_[0])/$_[1]) ) =~ tr/\x01/\x01/, + $/ = (!$_ || ($\ < $/)) ? $\ : $/ } map { $_*$_[1] } 0 .. ( length($_[0])/$_[1] - 1 ) @@ -49,10 +53,13 @@ sub min_flips { ## Next if it is the first chunk OR the value of $\ is less than the current min ($/) ## We set $/ to $\ otherwise we leave it as $/ ## - ## The resultant array consists of the running minimum in the examples - ## for ex 1: it is [1,1,1] - ## for ex 2: it is [1,1] - ## for ex 3: it is [2,1,1] + ## The resulting array consists of the value for the node and the running minimum in the examples + ## + ## for ex 1: it is [0,0,0,0] + ## for ex 2: it is [1,1,2,1,1,1] + ## for ex 3: it is [1,1,1,1] + ## for ex 4: it is [2,2,2,2] + ## for ex 5: it is [2,2,1,1,1,1] ## ## We need the last value of this so we wrap the list into an array ref and take the last element ## -- cgit