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..25befeef39 --- /dev/null +++ b/challenge-089/james-smith/perl/ch-2.pl @@ -0,0 +1,34 @@ +#!/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; +}