diff options
| author | drbaggy <js5@sanger.ac.uk> | 2020-09-14 09:11:36 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2020-09-14 09:11:36 +0100 |
| commit | 1c8db1f9b0e158f047b8854a1b5a4d9a1d8cd10b (patch) | |
| tree | 8e983cecb7e5cd8202fd9dfd51a18f6284114ea7 /challenge-078 | |
| parent | 3e528a8fb023c20355d619bee624d261922274d4 (diff) | |
| download | perlweeklychallenge-club-1c8db1f9b0e158f047b8854a1b5a4d9a1d8cd10b.tar.gz perlweeklychallenge-club-1c8db1f9b0e158f047b8854a1b5a4d9a1d8cd10b.tar.bz2 perlweeklychallenge-club-1c8db1f9b0e158f047b8854a1b5a4d9a1d8cd10b.zip | |
#78 solutions... kept nice and short!
Diffstat (limited to 'challenge-078')
| -rw-r--r-- | challenge-078/james-smith/README.md | 60 | ||||
| -rwxr-xr-x | challenge-078/james-smith/perl/ch-1.pl | 17 | ||||
| -rwxr-xr-x | challenge-078/james-smith/perl/ch-2.pl | 25 |
3 files changed, 85 insertions, 17 deletions
diff --git a/challenge-078/james-smith/README.md b/challenge-078/james-smith/README.md index 54043e40b0..74219c000c 100644 --- a/challenge-078/james-smith/README.md +++ b/challenge-078/james-smith/README.md @@ -1,34 +1,60 @@ Solutions by James Smith. -# Challenge 1 - Coins Sum +# Challenge 1 - leader -This is just begging for a recursive solution. +There are two solutions to this - the naive one works left to right, but the optimal one runs right to left. ```perl -sub csm { - my $t = shift; - return @{$mem{"$t @_"}||=[map {my $a=$_; $t==$a?[$a]: - map {[$a,@{$_}]} csm($t-$a,grep {$a<=$_&&$_<=$t} @_)} @_] }; +sub leader { ## Most efficient way is to work backwards on this rather + ## than forwards... + + return 0 unless @_; ## If nothing passed return 0 as requested. + + my @R = my $max = pop @_; ## Last one will always be a "leader"... + foreach ( reverse @_ ) { ## Work forward and unshift the value if it is now a leader + unshift @R, $max = $_ if $max < $_; ## greater than max value (and update max at the same time) + } + + return @R; ## Return array of leaders... } ``` Notes: - * %mem is a memoisation cache as it helps to not need to re-compute higher totals more than once - speeds up searches for large coin sums... not essential but nice to have + * This is an O(n) solution where the forward solution is O(n^2); + +# Challenge 2 - left rotate -How it works: +This is a simpler challenge as this is something Perl is even better at - rotating an array is just +an array slice of the array with the indicies itself rotated... - * Loop through all coin values available - * if the coin is the same as the amount required return a single array containing that value; - * if not remove that from the amount required and call again. For all values returned prepend the coin value to each array in the list - * when calling again remove any coins which are less than the "current coin" and greater than the amount required +The index rotation is easy: "offset" .. "size of list", 0 .. ("offset" - 1); -Caveats & assumptions: +So the code reduces to: - * No input checking is performed - assumes the options passed are all valid and greater than 0; +```perl +sub rotate { + my $a = shift; + ## First parameter is an arrayref containing the values to be rotated + ## Remaining parameters are the offsets for each rotation + + ## This is a great use of array slicing to achieve what we need + ## Indexes go from offset -> size-1 & 0 -> offset-1 + ## Perl nicely handles the case where the value to the left of + ## the double dot is higher than the value to the right + + print " [@{[ @{$a}[ $_..(@{$a}-1), 0..($_-1) ] ]}]\n" foreach @_; + + ## Let us use the @{[ ]} trick to embed content into the print + ## statement - this is a very useful and often under used feature + ## of perl which makes for simpler code when rendering output... + ## this is nice because print "@A" an print @A are subtly different + ## with the "@A" putting spaces (default value of $") +} +``` -# Challenge 2 - Histogram rectangle +Notes: -Much simpler this time. + * We use Arrayref slice notation @{ $arrayref }[ @index_list ] to do the rotation -First we get the size of the box (max value) and render chart then we look for the maximum rectangle size - which is computed as the maximum value of the distance between any two points (inclusive) multiplied by the lowest value in between the two values. (Maxi-min problem) + * We use "@{[ ... ]}" string interpolation to insert these values into the output... diff --git a/challenge-078/james-smith/perl/ch-1.pl b/challenge-078/james-smith/perl/ch-1.pl new file mode 100755 index 0000000000..7880f7169a --- /dev/null +++ b/challenge-078/james-smith/perl/ch-1.pl @@ -0,0 +1,17 @@ +#!/usr/local/bin/perl +use strict; +use warnings; + +print "@{[ leader( qw(9 10 7 5 6 1) ) ]}\n"; ## Example from challenge +print "@{[ leader( qw(3 4 5) ) ]}\n"; ## Example from challenge +print "@{[ leader( qw() ) ]}\n"; ## Null condition to return (0) from challenge + +sub leader { + ## Most efficient way is to work backwards on this rather than forwards... + return 0 unless @_; ## If nothing passed return 0 as requested. + my @R = my $max = pop @_; ## Last one will always be a "leader"... + foreach ( reverse @_ ) { ## Work forward and unshift the value if it is now a leader + unshift @R, $max = $_ if $max < $_; ## greater than max value (and update max at the same time) + } + return @R; ## Return array of leaders... +} diff --git a/challenge-078/james-smith/perl/ch-2.pl b/challenge-078/james-smith/perl/ch-2.pl new file mode 100755 index 0000000000..2b5a498903 --- /dev/null +++ b/challenge-078/james-smith/perl/ch-2.pl @@ -0,0 +1,25 @@ +#!/usr/local/bin/perl +use strict; +use warnings; + +rotate( [qw(10 20 30 40 50)], 3, 4 ); ## example from challenge +rotate( [qw( 7 4 2 6 3)], 1, 3, 4 ); ## example from challenge + +sub rotate { + my $a = shift; + ## First parameter is an arrayref containing the values to be rotated + ## Remaining parameters are the offsets for each rotation + + ## This is a great use of array slicing to achieve what we need + ## Indexes go from offset -> size-1 & 0 -> offset-1 + ## Perl nicely handles the case where the value to the left of + ## the double dot is higher than the value to the right + + print " [@{[ @{$a}[ $_..(@{$a}-1), 0..($_-1) ] ]}]\n" foreach @_; + + ## Let us use the @{[ ]} trick to embed content into the print + ## statement - this is a very useful and often under used feature + ## of perl which makes for simpler code when rendering output... + ## this is nice because print "@A" an print @A are subtly different + ## with the "@A" putting spaces (default value of $") +} |
