ETOOBUSY š minimal blogging for the impatient
PWC089 - GCD Sum
TL;DR
Here we are with TASK #1 from the Perl Weekly Challenge #089. Enjoy!
The challenge
You are given a positive integer
$N
. Write a script to sum GCD of all possible unique pairs between1
and$N
.
The questions
I can only guess that an input of 1
yields a 0
, which is probably
something that can be argued. Is the sum of ānothingā 0
?
But apart from this and what to do with invalid inputā¦ I canāt find anything particularly naggy to ask.
The solution
I have to be honest: I hate manwar.
Oh wait! Donāt get me wrong! My hate is in the same spirit as lazyness, impatience and hubris are the virtues of a programmer - i.e. I do in a very particular (and humorous) sense.
Wellā¦ where does this hatred come from? Itās simple: not only these challenges force me to think, but more often than Iām willing to admit they make me feel a combination of stupid and lazy (in a bad sense).
For so many of them thereās an inner voice that tells me that my simple, boring, immediate go-to solution is not really what we are supposed to come up with. Then thereās another inner voice that argues that itās a solution and it might be good in a lot of situation, so until we (at this point itās a mess of inner personas talking) know that itās not sufficient the problem is not worth any more time.
And yet thereās an inner party (yes, all these personas had to organize and elect a leader because there were too many of them) that argues that these challenges are supposed to emerge our thought process, and I tend to lean on the boring, inefficient side a bit too much.
So there I am thinking a lot, with a plethora of persona arguing in my head, and with the sensation that yes, thereās got to be a better way to do the task. OK, Iāll wait to read it from Abigailās solution this week too š
Soā¦ letās come to the task at hand. This time Iāll go straight to the solution:
#!/usr/bin/env perl
use 5.024;
use warnings;
use experimental qw< postderef signatures >;
no warnings qw< experimental::postderef experimental::signatures >;
sub gcd { my ($A, $B) = @_; ($A, $B) = ($B % $A, $A) while $A; return $B }
sub GCD_sum ($N) {
my $sum = $N - 1; # gcd(1, $x) = 1
for my $lo (2 .. $N - 1) {
$sum += gcd($lo, $_) for $lo + 1 .. $N;
}
return $sum;
}
say GCD_sum(shift || 4);
The gcd
function is just Euclidās algorithm in a one-liner.
The main function starts the sum from $N - 1
because the greatest common
divisor by any positive integer and 1
is justā¦ 1
. We are dealing with
distinct pairs, so we cannot count $(1, 1)$.
The two nested loops make sure that thereās no pair of integers, and just calculates the greatest common divisor betewen any possible applicable pair.
I guess this might be enhanced butā¦ well, go back to the start of this section!