Find the GCD that lies in given range


The problem states that we need to find the GCD that lies in the given range. We will be given two positive integers, x and y and two integers p and q which will be the range as [p,q]. We need to find out the GCD (greatest common divisor) of the numbers x and y falling under the range [p,q]. GCD, known as greatest common divisor in mathematics, is the greatest positive integer dividing each of two given positive integers. The given integers must not be zero. It is represented as gcd(x,y) for any two positive integers x and y.

For example, we are given two positive integers 6 and 9. The greatest common divisor, gcd(6,9) will be 3 as it is the highest number dividing both the numbers.

But in this problem, we need to find the greatest common divisor of the two given positive integers that fall under the specified range. Let’s understand the problem with examples. We will be given 4 numbers as input x and y to find the gcd of these numbers and two numbers indicating the range of gcd i.e. [p,q].

INPUT : x=8 , y=12 , p=1 , q=3

OUTPUT : 2

Explanation − Since the greatest common divisor of the given two numbers x and y is 4. But 4 does not come under the range [1,3]. The greatest common divisor falling under the range [1,3] is 2 which is our required output.

INPUT : x=17 , y=15 , a=5 , b=10

OUTPUT : -1

Explanation − The greatest common divisor of the numbers 17 and 15 is 1. Since 1 does not lie in the given range [5,10]. When there is no common divisor in the given range we need to print -1 as our output.

Algorithm

The algorithm that we will use to solve the problem is quite simple and related to mathematics. First, we will find gcd (greatest common divisor) of the numbers x and y. In C++, there is an inbuilt function named gcd() which returns the greatest common divisor of the number as output.

Syntax

int divisor=gcd(x,y);

We can also use an efficient approach to the Euclidean algorithm to find gcd of two numbers. Both work at the same time complexity i.e. O(log(min(x,y)).

Now, we can conclude using simple laws of arithmetic that the number dividing the gcd of two numbers will also divide the two numbers itself. So iterating in a for loop from i=1 to sqrt(gcd(x,y)) will help us to get all the common divisors of the number.

Then, check for every i until sqrt(gcd(x,y)) that i divides gcd(x,y) or not. If i divides gcd(x,y) then we can say that gcd(x,y)/i will also be the divisor of gcd, thus concluding it will also be the common divisor of numbers x and y.

Let us understand this concept with an example. Assume x and y to be 32 and 48. The gcd(18,27) is 16. So in this case we will iterate from i=1 to i<=4 which is sqrt(16). Let's consider i=2. Here i divide gcd(18,27) i.e. 16/2 which equals to 8. So gcd(x,y)/i will also divide gcd(x,y) to give i.

NOTE − If a number n, is divided by any number x to give y which can be represented as $\frac{n}{x}\:=\:y$ then y will also divide n to give x $(x\:\times\:y\:=\:n)$.

This algorithm can be the most efficient approach to solve this problem. While following this algorithm, we will keep checking if the common divisor lies in the range [a,b]. If it lies, we will keep updating the divisor in a variable using max() function to get the greatest common divisor within the range.

Syntax for max() function

int m = max(a,b);

It returns the maximum of a and b.

Approach

Below is the approach that we will follow −

  • Initialise a function to calculate the greatest common divisor lying within the given range.

  • Calculate the gcd of two given positive numbers x and y.

  • Initialise a variable name ans = -1.

  • Iterate in a for loop from i=1 to i<=sqrt(gcd(x,y)) and keep checking if i divides gcd(x,y).

  • If (gcd(x,y)%i)=0, check if i lies in the range [a,b] and if it does store it in ans using max() function so that we get the greatest common divisor lying in the range.

  • Also check if gcd/i lies in the range and if it does then again update the value of ans using max() function.

  • Return ans once we are done with all the iteration in for loop.

Example

The implementation of the approach in C++ −

#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;

// to calculate gcd of two numbers using Euclidean algorithm
int gcd(int a, int b){
   if(a == 0)
   return b;
   return gcd(b % a, a);
}

//function to calculate greatest common divisor in the given range [a,b]
int build(int x, int y, int a, int b) {

   //using C++ inbuilt library to calculate gcd of given numbers
   int z = gcd(x, y); //we can use euclidean algorithm too as an alternative
   int ans = -1; //storing -1 for the case when no common divisor lies in the range
   for(int i = 1; i<=sqrt(z); i++) { //iterating until sqrt(z) because either of two factors
      //of a number must be less than square root of the number
      if(z % i == 0) {
         if(i >= a && i <= b) //checking it i lies in the range
         ans = max(ans, i); //storing maximum value
         if((z / i) >= a && (z / i) <= b)
         ans = max(ans, z / i);
      }
   }
   return ans;
}
int main() {
   int x, y, a, b;
   x=24, y=42, a=3, b=9;
   cout << build(x, y, a, b) <<" is the gcd that lies in range ["<<a<<","<<b<<"]"<<endl;
   return 0;
}

Output

6 is the gcd that lies in range [3,9]

Time Complexity : O(log(min(x,y)) + sqrt(z)) , where z is the greatest common divisor of two numbers x and y.

Space Complexity : O(1) , since no extra space is used.

Conclusion

We discussed the approach to solve the problem to find the gcd of two numbers lying in the range [a,b]. This is how we can solve the above problem in C++ using a variety of different functions.

I hope you find this article helpful and clear all your concepts regarding the problem.

Updated on: 16-Mar-2023

345 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements