diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2021-08-07 00:47:12 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-08-07 00:47:12 +0100 |
| commit | 16117c591af62afe862b98210306827624258a4f (patch) | |
| tree | 06d52ea6fccc72ec022fa7dfce94b3ebb5e5ab89 /challenge-124 | |
| parent | 3bed073502b1f6706dea2c3740cadd3aea2b9538 (diff) | |
| parent | 9d1845a3fc2d4ff8d120d2095b552a2b250ba499 (diff) | |
| download | perlweeklychallenge-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.md | 15 | ||||
| -rw-r--r-- | challenge-124/james-smith/perl/ch-2.pl | 26 | ||||
| -rw-r--r-- | challenge-124/james-smith/php/ch-2.php | 20 |
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 ); +} |
