diff options
| author | Mohammad S Anwar <Mohammad.Anwar@yahoo.com> | 2020-11-30 21:23:43 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-30 21:23:43 +0000 |
| commit | 2b5fd26874f97b82f5a94c8f729b342ce17641d8 (patch) | |
| tree | 9cee0bc010359bbcd497aaf757f3625b2226ca97 | |
| parent | 32245ed4b801c8c3de24176248431e6bfa5234b2 (diff) | |
| parent | 67b4c3af526957d33e824e99216b8ee4c8dc18c9 (diff) | |
| download | perlweeklychallenge-club-2b5fd26874f97b82f5a94c8f729b342ce17641d8.tar.gz perlweeklychallenge-club-2b5fd26874f97b82f5a94c8f729b342ce17641d8.tar.bz2 perlweeklychallenge-club-2b5fd26874f97b82f5a94c8f729b342ce17641d8.zip | |
Merge pull request #2889 from drbaggy/master
Solutions - added comment why middle square is 5
| -rw-r--r-- | challenge-089/james-smith/perl/ch-1.pl | 43 | ||||
| -rw-r--r-- | challenge-089/james-smith/perl/ch-2.pl | 79 |
2 files changed, 122 insertions, 0 deletions
diff --git a/challenge-089/james-smith/perl/ch-1.pl b/challenge-089/james-smith/perl/ch-1.pl new file mode 100644 index 0000000000..0e79706771 --- /dev/null +++ b/challenge-089/james-smith/perl/ch-1.pl @@ -0,0 +1,43 @@ +#!/usr/local/bin/perl + +use strict; + +use warnings; +use feature qw(say); +use Test::More; + +is( gcd_sum(1), 0 ); +is( gcd_sum(2), 1 ); +is( gcd_sum(3), 3 ); +is( gcd_sum(4), 7 ); +is( gcd_sum(5), 11 ); +is( gcd_sum(6), 20 ); +is( gcd_sum(7), 26 ); +is( gcd_sum(8), 38 ); +is( gcd_sum(9), 50 ); +is( gcd_sum(10), 67 ); + +done_testing(); + +sub gcd_sum { + my $n = shift; + my $sum = 2*$n-2; ### We can pull out the GCDs with 1 as either side + ### Note because of the optimization below we only + ### Remove -2 as we remove another one is the + ### special case where $x==2; + foreach my $x ( 2..$n ) { + ## Note that the gcd is symetric gcd($m,$n) == gcd($m,$m-$n) where $n between 1 & $m-1 + $sum += 2*gcd( $x, $_ ) foreach 2..$x/2; + ## We have counted the middle value twice if $x is even.... so remove one of them... + $sum -= $x/2 unless $x%2; + } + return $sum; +} + +sub gcd { + my( $n,$m ) = @_; + ## The way we have set up gcd sum we know $n>$m in all cases + ## So don't need to check m will always be <= n + ($n,$m) = ( $m, $n % $m ) while $n % $m; + return $m; +} diff --git a/challenge-089/james-smith/perl/ch-2.pl b/challenge-089/james-smith/perl/ch-2.pl new file mode 100644 index 0000000000..b9c086b9bb --- /dev/null +++ b/challenge-089/james-smith/perl/ch-2.pl @@ -0,0 +1,79 @@ +#!/usr/local/bin/perl + +use strict; +use warnings; +use feature qw(say); + +say map { "@{$_}\n" } @{$_} foreach magic(); + +## We now $e must be 5... so we only need to loop through values 1..9 +## for both a and b with possible values such that $c < 10 +## the inner loop is then executed just 32 times.... + +## We can generate all values if we only have a b & e +## If we do this we get the sums of the 2nd and 3rd row as 3e & 30-3e respectively +## For these to both be 15 e must be 5. + +sub magic { + my @solutions = (); + foreach my $a (1..4,6..9) { ## a can't be 5... + ## $b can't be 5, can't be $a and can't make $c 5 + foreach my $b ( grep { $_!=5 && $_!=$a && $a+$_!=10 } ($a<6?6-$a:1)..($a<6?9:14-$a) ) { + ## Only 32 get here! + + ## Check digits unique and between 1 and 9 { all digits can be computed in terms of a & b } + my $digits = [ [ $a, $b, 15-$a-$b ], + [ 20-2*$a-$b, 5, 2*$a+$b-10 ], + [ $a+$b-5, 10-$b, 10-$a ] ]; + + ## Convert into the required grid if numbers unique and 1..9 + push @solutions, $digits if '123456789' eq join q(), sort map {@{$_}} @{$digits}; + } + } + return @solutions; +} + +### Now the bit below is another solution.... + +## This looks at all the rules and applies them sequentially +## You need to follow upwards + +## We can generate all values if we only have a, b & e +## If we do this we get the sums of the 2nd and 3rd row as 3e & 30-3e respectively +## For these to both be 15 e must be 5. + +## As e is 5 we only have to loop over a - $a and b - $_. + +print + ## Render output... + map { + map( + { " [ @{$_} ]\n" } + @{$_} + ), + "\n" + } + ## Get magic square.... + map { + $a = $_; + ## Return square... + map { [ + [ $a , $_ , -$a - $_ + 15 ], + [ -2*$a - $_ + 20, 5, 2*$a + $_ - 10 ], + [ $a + $_ - 5, -$_ + 10, -$a + 10 ] + ] } + ## Now we filter a/b... + grep { 20 > 2*$a + $_ } # f is a single digit + grep { 10 < 2*$a + $_ } # ------- " --------- + grep { 25 != 3*$a + 2*$_ } # a != f ( f = 2a - b - 10 ) + grep { 20 != 3*$a + $_ } # a != d ( d = 20 - 2a - b ) + grep { 15 != $a + 2*$_ } # c != b + grep { 15 != 2*$a + $_ } # c != a ( c = 15 - a - b ) + grep { 10 != $a + $_ } # c != e ( 5 ) + grep { 0 != -$a + $_ } # a != b + grep { 5 != $_ } # b != e ( 5 ) + $a < 6 ? 6-$a .. 9 : 1 .. 14-$a # ensure c is a single digit number + } + 1..4 , 6..9; # a != e ( 5 ) + + |
