diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-08-04 04:51:22 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-04 04:51:22 +0100 |
| commit | 529323136f23f89044c8d2f8d8fbdbe9f61d6dea (patch) | |
| tree | 9cefbc22916c6a4c7757094a082b00d743182801 | |
| parent | 599d414248b540c24563384869fb63769c19942d (diff) | |
| parent | e729921dd04483439c90d55cdebe057e6602547a (diff) | |
| download | perlweeklychallenge-club-529323136f23f89044c8d2f8d8fbdbe9f61d6dea.tar.gz perlweeklychallenge-club-529323136f23f89044c8d2f8d8fbdbe9f61d6dea.tar.bz2 perlweeklychallenge-club-529323136f23f89044c8d2f8d8fbdbe9f61d6dea.zip | |
Merge pull request #4655 from simongreen-net/swg-124
sgreen solution to task 2 challenge 124
| -rw-r--r-- | challenge-124/sgreen/README.md | 4 | ||||
| -rw-r--r-- | challenge-124/sgreen/blog.txt | 1 | ||||
| -rwxr-xr-x | challenge-124/sgreen/perl/ch-2.pl | 89 |
3 files changed, 92 insertions, 2 deletions
diff --git a/challenge-124/sgreen/README.md b/challenge-124/sgreen/README.md index 1b1ced64d1..e025103f4b 100644 --- a/challenge-124/sgreen/README.md +++ b/challenge-124/sgreen/README.md @@ -1,3 +1,3 @@ -# The Weekly Challenge 123 +# The Weekly Challenge 124 -Solution by Simon Green. [Blog](https://dev.to/simongreennet/weekly-challenge-123-2flk) +Solution by Simon Green. [Blog](https://dev.to/simongreennet/weekly-challenge-124-2gi7) diff --git a/challenge-124/sgreen/blog.txt b/challenge-124/sgreen/blog.txt new file mode 100644 index 0000000000..822fd3f8aa --- /dev/null +++ b/challenge-124/sgreen/blog.txt @@ -0,0 +1 @@ +https://dev.to/simongreennet/weekly-challenge-124-2gi7 diff --git a/challenge-124/sgreen/perl/ch-2.pl b/challenge-124/sgreen/perl/ch-2.pl new file mode 100755 index 0000000000..6a955f9654 --- /dev/null +++ b/challenge-124/sgreen/perl/ch-2.pl @@ -0,0 +1,89 @@ +#!/usr/bin/env perl + +use strict; +use warnings; +use feature 'say'; + +use List::Util qw(none sum); + +sub _get_next_combination { + my ( $size, @combination ) = @_; + + # First time run + if ( scalar(@combination) == 0 ) { + my $half_size = int( $size / 2 ); + return ( 0 .. $half_size - 1 ); + } + + # How many numbers do we need to change + my $count = 0; + while ( ++$count ) { + last if $combination[ -$count ] < $size - $count; + + # There are no more combinations + return if $count == int( $size / 2 ); + } + + # Add one to the first number + $combination[ -$count ]++; + + # If there is any other numbers to change, add 1 from the previous digit + foreach my $i ( $#combination - $count + 2 .. $#combination ) { + $combination[$i] = $combination[ $i - 1 ] + 1; + } + + return @combination; +} + +sub main { + my @values = @_; + my $size = @values; + + # Sanity check + die "You must provide two or more integers\n" unless $size > 1; + foreach my $x (@values) { + die "The value '$x does not appear to be a integer\n" unless $x =~ /^-?[0-9]+$/; + } + + # Get half the sum of all the numbers. This is the target we want to + # hit for one of the sets. + my $target = sum(@values) / 2; + + # This records the best set we've found so far. + my $best_sum = 'inf'; + my @first_set = (); + my @combination = (); + + # Go through all possible combinations of the first set + while ( @combination = _get_next_combination( $size, @combination ) ) { + + # Calculate the difference between the sum of this set and the target + my $sum = sum( @values[@combination] ); + my $diff = abs( $sum - $target ); + + if ( $diff == 0 ) { + # We've find the best combination + @first_set = @combination; + last; + } + elsif ( $diff < $best_sum ) { + # We've found a better combination + $best_sum = $diff; + @first_set = @combination; + } + + } + + # Get the second set (everything not in the first set!) + my @second_set = grep { + my $i = $_; + none { $i == $_ } @first_set + } ( 0 .. $#values ); + + # Print the results + say 'Subset 1 = (', join( ', ', @values[@first_set] ), ')'; + say 'Subset 2 = (', join( ', ', @values[@second_set] ), ')'; + +} + +main(@ARGV); |
