aboutsummaryrefslogtreecommitdiff
path: root/challenge-124
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2021-08-07 00:47:12 +0100
committerGitHub <noreply@github.com>2021-08-07 00:47:12 +0100
commit16117c591af62afe862b98210306827624258a4f (patch)
tree06d52ea6fccc72ec022fa7dfce94b3ebb5e5ab89 /challenge-124
parent3bed073502b1f6706dea2c3740cadd3aea2b9538 (diff)
parent9d1845a3fc2d4ff8d120d2095b552a2b250ba499 (diff)
downloadperlweeklychallenge-club-16117c591af62afe862b98210306827624258a4f.tar.gz
perlweeklychallenge-club-16117c591af62afe862b98210306827624258a4f.tar.bz2
perlweeklychallenge-club-16117c591af62afe862b98210306827624258a4f.zip
Merge pull request #4668 from drbaggy/master
Tidied code and added PHP solution
Diffstat (limited to 'challenge-124')
-rw-r--r--challenge-124/james-smith/README.md15
-rw-r--r--challenge-124/james-smith/perl/ch-2.pl26
-rw-r--r--challenge-124/james-smith/php/ch-2.php20
3 files changed, 36 insertions, 25 deletions
diff --git a/challenge-124/james-smith/README.md b/challenge-124/james-smith/README.md
index 96211096d5..a639f2ace2 100644
--- a/challenge-124/james-smith/README.md
+++ b/challenge-124/james-smith/README.md
@@ -177,6 +177,9 @@ repeat 180 [
penup
```
+
+You may ask why we only rotate right 89 to start the circle. If we start by rotating right then the circle will be off-set by "5" units to the right - we either have to do `right 90` `forward 5` `left 2` then `repeat` for `179`. And finish with another `right 5`. (This means the centre of one of the sides is at the top of the cross - or we can rotate the shape by 1 degree and have it stand on one of it's points)
+
# Task 2 - Tug of War
***You are given a set of `$n` integers `(n1, n2, n3, ...)`. Write a script to divide the set in two subsets of `n/2` sizes each so that the difference of the sum of two subsets is the least. If `$n` is even then each subset must be of size `$n/2` each. In case `$n` is odd then one subset must be `($n-1)/2` and other must be `($n+1)/2`.***
@@ -200,18 +203,14 @@ So to start - we allocate person 1 to group 1, and set the difference to his wei
```perl
sub match_teams {
my( $diff, @n ) = @_;
- separate( 1 + int(@n/2), [$diff], [], $diff, my $best = [], @n );
- return "Team 1: [@{$best->[0]}]; Team 2: [@{$best->[1]}]; difference $best->[2]";
+ separate( 1 + int(@n/2), [$diff], [], $diff, my $best = [1e300], @n );
+ return "Team 1: [@{$best->[1]}]; Team 2: [@{$best->[2]}]; difference $best->[0]";
}
sub separate {
my($maxsize,$team1,$team2,$diff,$be,@nums) = @_;
unless(@nums) {
- if( !defined $be->[0] || $be->[2]>abs $diff ) {
- $be->[0] = $team1;
- $be->[1] = $team2;
- $be->[2] = abs $diff;
- }
+ @{$be} = ($team1, $team2, abs $diff) if $be->[0]>abs $diff;
return;
}
my $next = shift @nums;
@@ -220,7 +219,7 @@ sub separate {
}
```
### Notes:
- * Notice the yoda inequality `$be->[2]>abs $diff` - it makes it clearer that you are only computing the absolute value of `$diff` not that of `$diff < $be->[2]`.
+ * Notice the yoda inequality `$be->[0]>abs $diff` - it makes it clearer that you are only computing the absolute value of `$diff` not that of `$diff < $be->[0]`.
* `$team1` / `$team2` are refs - so when we update them we make copies `[@{$team2},$next]` rather than pushing to them.
* We keep the running total as it avoids the need to do the sum each time.
diff --git a/challenge-124/james-smith/perl/ch-2.pl b/challenge-124/james-smith/perl/ch-2.pl
index 6b360cd40d..ba27205aae 100644
--- a/challenge-124/james-smith/perl/ch-2.pl
+++ b/challenge-124/james-smith/perl/ch-2.pl
@@ -4,11 +4,8 @@ use strict;
use warnings;
use feature qw(say);
-use Test::More;
use Benchmark qw(cmpthese timethis);
-use Data::Dumper qw(Dumper);
-done_testing();
say match_teams( map { $_*10 } 1..15 );
say match_teams( map { $_*10 } 1..10 );
say match_teams( qw(10 -15 20 30 -25 0 5 40 -5) );
@@ -16,7 +13,6 @@ say match_teams( qw(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 7
timethis(1000, sub { match_teams( map { $_*10 } 1..10 ); } );
timethis(1000, sub { match_teams( map { $_*10 } 1..12 ); } );
timethis(1000, sub { match_teams( map { $_*10 } 1..14 ); } );
-exit;
timethis(100, sub { match_teams( map { $_*10 } 1..16 ); } );
timethis(100, sub { match_teams( map { $_*10 } 1..18 ); } );
timethis(100, sub { match_teams( map { $_*10 } 1..20 ); } );
@@ -34,25 +30,21 @@ sub match_teams {
##
## $best - stores the result!!
##
- ## $best->[0] = array of team 1 members
- ## $best->[1] = array of team 2 members
- ## $best->[2] = difference between scores
+ ## $best->[0] = difference between scores
+ ## $best->[1] = array of team 1 members
+ ## $best->[2] = array of team 2 members
my( $diff, @names ) = @_;
- separate( 1 + int( @names/2 ), [$diff], [], $diff, my $best = [], @names );
- return "Team 1: [@{$best->[0]}]; Team 2: [@{$best->[1]}]; difference $best->[2]";
+ separate( 1 + int( @names/2 ), [$diff], [], $diff, my $best = [1<<63], @names );
+ return "Team 1: [@{$best->[1]}]; Team 2: [@{$best->[2]}]; difference $best->[0]";
}
sub separate {
my( $maxsize, $team1, $team2, $diff, $be, @nums ) = @_;
- unless(@nums) {
- if( !defined $be->[0] || $be->[2]>abs $diff ) {
- $be->[0] = $team1; ## If this is the first time we have got to the end of the list
- $be->[1] = $team2; ## OR we have got to the end of the list and have a better solution
- $be->[2] = abs $diff; ## store this in $be - can't just do $be = [ , , ] as this would
- } ## change the pointer and wouldn't be preserved....
- return;
- }
+ return ( $be->[0] > abs $diff ) && ( @{$be} = ( abs $diff, $team1, $team2 ) ) unless @nums;
+ ## If we get to the end of the list and have a better solution (smaller diff)
+ ## store info in $be - can't just do $be = [ , , ] as this would
+ ## change the pointer and wouldn't be preserved....
my $next = shift @nums; ## Get the next person and allocate to team 1 and/or team 2 depending
## on whether the teams have space...
separate( $maxsize, [@{$team1},$next], $team2, $diff+$next, $be, @nums ) if @{$team1} < $maxsize;
diff --git a/challenge-124/james-smith/php/ch-2.php b/challenge-124/james-smith/php/ch-2.php
new file mode 100644
index 0000000000..2a888e40ee
--- /dev/null
+++ b/challenge-124/james-smith/php/ch-2.php
@@ -0,0 +1,20 @@
+<?php
+
+echo match_teams([1,2,3,4,5,6,7,8,9,10]);
+echo match_teams([1,2,3,4,5,6,7,8,9]);
+echo match_teams([1,1,1,1,1,1,3,1,10]);
+
+function match_teams( $teams ) {
+ $d = array_shift( $teams );
+ $bt =[1e99];
+ separate( 1 + floor( sizeof($teams)/2 ), [$d], [], $d, $bt, $teams );
+ return sprintf( "T1: [%s]; T2: [%s]; Diff %d\n",
+ implode( ' ', $bt[1] ), implode( ' ', $bt[2] ), $bt[0] );
+}
+
+function separate( $m, $t1, $t2, $d, &$b, $w ) { // & in front of $b as pass by reference!
+ if(!sizeof($w)) return ( $b[0]>abs($d) ) && ( $b = [abs($d),$t1,$t2] );
+ $n = array_shift( $w );
+ if( sizeof($t1)<$m ) separate( $m, array_merge($t1,[$n]), $t2, $d+$n, $b, $w );
+ if( sizeof($t2)<$m ) separate( $m, $t1, array_merge($t2,[$n]), $d-$n, $b, $w );
+}