aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrbaggy <js5@sanger.ac.uk>2021-01-25 14:50:16 +0000
committerdrbaggy <js5@sanger.ac.uk>2021-01-25 14:50:16 +0000
commitc4a60d0ec86e18c9ec046f7f341b41bb747e61fd (patch)
treea571f28f0ae6534730ecfc81d3f21477e607e129
parent0b86f89009795ee7606421f61ad9bed82d45b0d7 (diff)
downloadperlweeklychallenge-club-c4a60d0ec86e18c9ec046f7f341b41bb747e61fd.tar.gz
perlweeklychallenge-club-c4a60d0ec86e18c9ec046f7f341b41bb747e61fd.tar.bz2
perlweeklychallenge-club-c4a60d0ec86e18c9ec046f7f341b41bb747e61fd.zip
remove the for loops and make this a map list....
-rw-r--r--challenge-097/james-smith/perl/ch-2.pl50
1 files 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];
}