aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammad S Anwar <Mohammad.Anwar@yahoo.com>2020-11-30 21:23:43 +0000
committerGitHub <noreply@github.com>2020-11-30 21:23:43 +0000
commit2b5fd26874f97b82f5a94c8f729b342ce17641d8 (patch)
tree9cee0bc010359bbcd497aaf757f3625b2226ca97
parent32245ed4b801c8c3de24176248431e6bfa5234b2 (diff)
parent67b4c3af526957d33e824e99216b8ee4c8dc18c9 (diff)
downloadperlweeklychallenge-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.pl43
-rw-r--r--challenge-089/james-smith/perl/ch-2.pl79
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 )
+
+