diff options
| author | drbaggy <js5@sanger.ac.uk> | 2020-09-28 22:03:39 +0100 |
|---|---|---|
| committer | drbaggy <js5@sanger.ac.uk> | 2020-09-28 22:03:39 +0100 |
| commit | 0093bbf3c47acc6b7ed4a3bc749767a6858a4d5c (patch) | |
| tree | 9a88755f3b2a408fd3c27b1b5ef025bace77ed18 | |
| parent | 0a2787dfeb4c5def8555c80758d3cd3e5a30a39a (diff) | |
| download | perlweeklychallenge-club-0093bbf3c47acc6b7ed4a3bc749767a6858a4d5c.tar.gz perlweeklychallenge-club-0093bbf3c47acc6b7ed4a3bc749767a6858a4d5c.tar.bz2 perlweeklychallenge-club-0093bbf3c47acc6b7ed4a3bc749767a6858a4d5c.zip | |
challenge 80
| -rw-r--r-- | challenge-080/james-smith/README.md | 43 | ||||
| -rw-r--r-- | challenge-080/james-smith/perl/ch-1.pl | 18 | ||||
| -rw-r--r-- | challenge-080/james-smith/perl/ch-2.pl | 31 |
3 files changed, 53 insertions, 39 deletions
diff --git a/challenge-080/james-smith/README.md b/challenge-080/james-smith/README.md index 96284e7deb..a3404cb84a 100644 --- a/challenge-080/james-smith/README.md +++ b/challenge-080/james-smith/README.md @@ -1,45 +1,10 @@ Solutions by James Smith. -# Challenge 1 - Count Set Bits +# Challenge 1 - Smallest Positive Number -This is a really interesting challenge - there is a really quick naive solution which is to do the -counting - but that is an O(n log(n)) problem so as n gets large (to values where the modulus -calculation is required) then this gets very slow. +After testing two solutions (using sort and using hash keys) it became obvious the best way of handling this is to sort the +ve numbers and them loop through them to find the first missing one (the first number which has the value in the array not equal to the 1-based index) -There is an O(log(n)) solution which means breaking the sums into chunks which are easy to sum. +# Challenge 2 - Count candies -For the numbers 1 .. (2^n-1) you can see that the sum of the bits is n(2^n)/2 +This is a simple sweep approach applying the b) rule multiple times until the counting stops! -[ There are 2^n numbers (including 0) and you can represent number in n bits, and exactly half of the bits are 1 ] - -We can then use this to work out the sums of the bit counts.. - -First we get a bit representation of "$i+1" - -so e.g. for i = 22 - the array is 1 0 1 1 1 - -Loop through the bits and use the count method above to count the lower bits -of each group (ignore any where the value in the bit array is 0) -The higher bits are counted by multiplying the size of the group by the bits -in the "higher bit" e.g. 16, 20, 22 below... What we note though is that this -number increases by 1 each time that we loop through the array - -So in the example above the chunks become: - -``` - 1..15 - split this into 16 x "0" & 0..15 - total is 2^4 * 0 + 4(2^4)/2 = 32 -16..19 - split this into 4 x "16" & 0..3 - total is 2^2 * 1 + 2(2^2)/2 = 8 -20..21 - split this into 2 x "20" & 0..1 - total is 2^1 * 2 + 1(2^1)/2 = 5 -22 - split this into 1 x "22" & 0 - total is 2^0 * 3 + 0(2^0)/2 = 3 - 48 -``` - -# Challenge 2 - trapped rain water - -Much simpler challenge this time - we just need to work out how much water is trapped. -So for any column we need to work out the maximum height of rocks to the left and right -of the column, if neither of these are higher than the height of the current column no -water is trapped. Otherwise the amount of water is trapped is the minimum of these two -values minus the height of the column. - -To enhance the image - I've also added "~~"s to indicate where the water is trapped diff --git a/challenge-080/james-smith/perl/ch-1.pl b/challenge-080/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..09526718d6 --- /dev/null +++ b/challenge-080/james-smith/perl/ch-1.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use feature qw(say); + +say smallest_number_sort(qw(200 1 -2 2 5 1000 -6 3000 ),1e6..1e7,6001..9001,3,4,3401..5900); +say smallest_number_sort(qw(5 2 -2 0)); +say smallest_number_sort(qw(1 8 -1)); +say smallest_number_sort(qw(2 0 -1)); + +sub smallest_number_sort { + my @q = sort { $a <=> $b } grep {$_>0} @_; ## Need +ve in order! + for( $_=1; $_ == shift @q; $_++ ) {} ## Loop through from 1.. exit loop if the array + ## value isn't equal to index (1-based) + return $_; ## return value... +} diff --git a/challenge-080/james-smith/perl/ch-2.pl b/challenge-080/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..9116f85539 --- /dev/null +++ b/challenge-080/james-smith/perl/ch-2.pl @@ -0,0 +1,31 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use feature qw(say); + +say candies( qw(1 2 2) ); +say candies( qw(1 4 3 2) ); + +sub candies { + my @ranks = @_; + my $prev_count = @candies = map { 1 } @ranks; ## First pass we set everything to 1! + my $flag; + do { + my $count = 0; + foreach( 0..(@ranks-2) ) { ## Loop through comparing element to next one - increase as approprite + + $candies[$_] = $candies[$_+1]+1 if ($ranks[$_] > $ranks[$_+1]) && ($candies[$_] <= $candies[$_+1]); + $candies[$_+1] = $candies[$_ ]+1 if ($ranks[$_] < $ranks[$_+1]) && ($candies[$_] => $candies[$_+1]); + + $count += $candies[$_ ]; ## by the time we get here we would have done both comparisons that + ## cause this entry to be updated.. + } + + $count += $candies[-1]; ## Add count for the last element... + + return $count if $count == $prev_count; ## Totals are the same so nothing been update can return + $prev_count = $count; + } while( 1 ); ## Infinite loop - will hit exit condition in loop...! +} |
