diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2020-10-25 12:35:28 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-10-25 12:35:28 +0000 |
| commit | d9b1a8fb57bde164178d562e599bf375a60eb38e (patch) | |
| tree | 9d229513cef60a83a40b0899d41c04864660ccce | |
| parent | a48ff2cd3f70a00492b6ab95394af1efa68e52c1 (diff) | |
| parent | 357753f6fc4471450af9755b156409b3be79a1c0 (diff) | |
| download | perlweeklychallenge-club-d9b1a8fb57bde164178d562e599bf375a60eb38e.tar.gz perlweeklychallenge-club-d9b1a8fb57bde164178d562e599bf375a60eb38e.tar.bz2 perlweeklychallenge-club-d9b1a8fb57bde164178d562e599bf375a60eb38e.zip | |
Merge pull request #2601 from jo-37/contrib
Solutions to challenge 083
| -rwxr-xr-x | challenge-083/jo-37/perl/ch-1.pl | 18 | ||||
| -rwxr-xr-x | challenge-083/jo-37/perl/ch-2.pl | 62 |
2 files changed, 80 insertions, 0 deletions
diff --git a/challenge-083/jo-37/perl/ch-1.pl b/challenge-083/jo-37/perl/ch-1.pl new file mode 100755 index 0000000000..ccacecf211 --- /dev/null +++ b/challenge-083/jo-37/perl/ch-1.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl + +use Test2::V0; + +sub inner_length { + local $_ = shift; + + # Split the string into words, pick all between the first and the + # last, join them and return the length. + length join '', splice @{[split qr{\s+}]}, 1, -1; + +} + +is inner_length('The Weekly Challenge'), 6, 'Example 1'; +is inner_length('The purpose of our lives is to be happy'), 23, 'Example 2'; +is inner_length('nothing intermediate'), 0, 'Out of scope: no inner words'; + +done_testing; diff --git a/challenge-083/jo-37/perl/ch-2.pl b/challenge-083/jo-37/perl/ch-2.pl new file mode 100755 index 0000000000..6a3d578b7b --- /dev/null +++ b/challenge-083/jo-37/perl/ch-2.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl + +use Test2::V0; +use List::Util 'sum'; +use List::MoreUtils 'pairwise'; +use Math::Utils 'copysign'; +use Benchmark 'cmpthese'; + +# Count the minimum number of sign flips to achieve the mimimum signed +# sum. The efford to find the solution with this brute-force +# implementation grows exponentially with the length of the given list +# of numbers. For larger lists a smarter approach is required. +sub minflips { + my ($minsum, $minflips) = ('inf'); + my $len = @_; + + # Take the sign flips from the ones in the binary representation of + # a counter. + foreach (map {sprintf "%0${len}b", $_} 1 .. 2**$len - 2) { + + # Apply ones in $_ as negative signs to the given numbers and + # sum these. + my $sum = sum pairwise {copysign $b, -$a} @{[split '']}, @_; + + # Skip sums out of range + next if $sum < 0 || $sum > $minsum; + + # Count the number of flips, i.e. the number of ones in $_. + my $flips = y/1/1/; + + # A smaller sum is taken as the new best solution or + # a sum achieved with less flips. + ($minsum, $minflips) = ($sum, $flips) + if $sum < $minsum || $flips < $minflips; + } + + $minflips; +} + +is minflips(3, 10, 8), 1, 'Example 1'; +is minflips(12, 2, 10), 1, 'Example 2'; +is minflips(2, 3, 5, 9, 4), 2; +is minflips(4, 1, 1, 1), 3; +is minflips(2, 1, 1, 1), 1; + +SKIP: { + skip 'optional benchmark', 3; + cmpthese 1, { + 15 => sub {is minflips(1 .. 15), 5}, + 16 => sub {is minflips(1 .. 16), 5}, + 17 => sub {is minflips(1 .. 17), 6} + } + + # s/iter 17 16 15 + # 17 2.33 -- -54% -78% + # 16 1.08 116% -- -53% + # 15 0.510 357% 112% -- + # +} + +done_testing; + |
