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 between 1 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!


Comments? Octodon, , GitHub, Reddit, or drop me a line!