Open In App

Smallest divisor of N closest to X

Last Updated : 19 Nov, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given two positive integers N and X, the task is to find the smallest divisor of N which is closest to X.

Examples:

Input: N = 16, X = 5 
Output:
Explanation: 
4 is the divisor of 16 which is closest to 5.

Input: N = 27, X = 15
Output:
Explanation:
9 is the divisor of 27 closest to 15.

Naive Approach: The simplest approach to solve the problem is to iterate through all the values up to N and find the closest one to X that divides N

Time Complexity: O(N)
Auxiliary Space: O(1)

Better Approach: A better idea is to iterate through all the divisors of N and check for the divisor closest to X.

Below is the implementation of the above approach:  

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the divisor of N
// closest to the target
int findClosest(int N, int target)
{
    int closest = -1;
    int diff = INT_MAX;
 
    // Iterate till square root of N
    for (int i = 1; i <= sqrt(N); i++) {
        if (N % i == 0) {
 
            // Check if divisors are equal
            if (N / i == i) {
 
                // Check if i is the closest
                if (abs(target - i) < diff) {
                    diff = abs(target - i);
                    closest = i;
                }
            }
            else {
 
                // Check if i is the closest
                if (abs(target - i) < diff) {
                    diff = abs(target - i);
                    closest = i;
                }
 
                // Check if n / i is the closest
                if (abs(target - N / i) < diff) {
                    diff = abs(target - N / i);
                    closest = N / i;
                }
            }
        }
    }
 
    // Print the closest value
    cout << closest;
}
 
// Driver Code
int main()
{
    // Given N & X
    int N = 16, X = 5;
 
    // Function Call
    findClosest(N, X);
 
    return 0;
}


Java




// Java program for the above approach
import java.util.*;
class GFG {
 
  // Function to find the divisor of N
  // closest to the target
  static void findClosest(int N, int target)
  {
    int closest = -1;
    int diff = Integer.MAX_VALUE;
 
    // Iterate till square root of N
    for (int i = 1; i <= (int)Math.sqrt(N); i++) {
      if (N % i == 0) {
 
        // Check if divisors are equal
        if (N / i == i) {
 
          // Check if i is the closest
          if (Math.abs(target - i) < diff)
          {
            diff = Math.abs(target - i);
            closest = i;
          }
        }
        else {
 
          // Check if i is the closest
          if (Math.abs(target - i) < diff)
          {
            diff = Math.abs(target - i);
            closest = i;
          }
 
          // Check if n / i is the closest
          if (Math.abs(target - N / i) < diff)
          {
            diff = Math.abs(target - N / i);
            closest = N / i;
          }
        }
      }
    }
 
    // Print the closest value
    System.out.println(closest);
  }
 
  // Driver code
  public static void main(String[] args)
  {
 
    // Given N & X
    int N = 16, X = 5;
 
    // Function Call
    findClosest(N, X);
  }
}
 
// This code is contributed by code_hunt.


Python3




# Python3 program for the above approach
from math import sqrt, floor, ceil
 
# Function to find the divisor of N
# closest to the target
def findClosest(N, target):
    closest = -1
    diff = 10**18
 
    # Iterate till square root of N
    for i in range(1, ceil(sqrt(N)) + 1):
        if (N % i == 0):
 
            # Check if divisors are equal
            if (N // i == i):
 
                # Check if i is the closest
                if (abs(target - i) < diff):
                    diff = abs(target - i)
                    closest = i
 
            else:
 
                # Check if i is the closest
                if (abs(target - i) < diff):
                    diff = abs(target - i)
                    closest = i
 
                # Check if n / i is the closest
                if (abs(target - N // i) < diff):
                    diff = abs(target - N // i)
                    closest = N // i
 
    # Print the closest value
    print(closest)
 
# Driver Code
if __name__ == '__main__':
   
    # Given N & X
    N, X = 16, 5
 
    # Function Call
    findClosest(N, X)
 
    # This code is contributed by mohit kumar 29


C#




// C# program for the above approach
using System;
class GFG {
 
  // Function to find the divisor of N
  // closest to the target
  static void findClosest(int N, int target)
  {
    int closest = -1;
    int diff = Int32.MaxValue;
 
    // Iterate till square root of N
    for (int i = 1; i <= Math.Sqrt(N); i++) {
      if (N % i == 0) {
 
        // Check if divisors are equal
        if (N / i == i) {
 
          // Check if i is the closest
          if (Math.Abs(target - i) < diff)
          {
            diff = Math.Abs(target - i);
            closest = i;
          }
        }
        else {
 
          // Check if i is the closest
          if (Math.Abs(target - i) < diff)
          {
            diff = Math.Abs(target - i);
            closest = i;
          }
 
          // Check if n / i is the closest
          if (Math.Abs(target - N / i) < diff)
          {
            diff = Math.Abs(target - N / i);
            closest = N / i;
          }
        }
      }
    }
 
    // Print the closest value
    Console.Write(closest);
  }
 
  // Driver code
  static void Main()
  {
 
    // Given N & X
    int N = 16, X = 5;
 
    // Function Call
    findClosest(N, X);
  }
}
 
// This code is contributed by divyeshrabadiya07


Javascript




<script>
// Javascript program for the above approach
 
// Function to find the divisor of N
// closest to the target
function findClosest(N, target)
{
    let closest = -1;
    let diff = Number.MAX_VALUE;
 
    // Iterate till square root of N
    for (let i = 1; i <= Math.sqrt(N); i++) {
    if (N % i == 0) {
 
        // Check if divisors are equal
        if (N / i == i) {
 
        // Check if i is the closest
        if (Math.abs(target - i) < diff)
        {
            diff = Math.abs(target - i);
            closest = i;
        }
        }
        else {
 
        // Check if i is the closest
        if (Math.abs(target - i) < diff)
        {
            diff = Math.abs(target - i);
            closest = i;
        }
 
        // Check if n / i is the closest
        if (Math.abs(target - N / i) < diff)
        {
            diff = Math.abs(target - N / i);
            closest = N / i;
        }
        }
    }
    }
 
    // Print the closest value
    document.write(closest);
}
 
// driver function
 
    // Given N & X
    let N = 16, X = 5;
 
    // Function Call
    findClosest(N, X);
     
    // This code is contributed by souravghosh0416.
</script>


Output: 

4

 

Time Complexity: O(sqrt(N))
Auxiliary Space: O(1)

Efficient Approach: The optimal idea is to pre-compute the divisors of all the numbers from 1 to N using a modified form of Sieve Of Eratosthenes and then use Binary Search to find the closest value to the given target.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Define macros
#define MAX 10000
 
vector<vector<int> > divisors(MAX + 1);
 
// Stores divisors for all numbers
// in the vector divisors
void computeDivisors()
{
    for (int i = 1; i <= MAX; i++) {
        for (int j = i; j <= MAX; j += i) {
 
            // i is the divisor and
            // j is the multiple
            divisors[j].push_back(i);
        }
    }
}
 
// Function to compare the closeness of the given
// target
int getClosest(int val1, int val2, int target)
{
    if (target - val1 >= val2 - target)
        return val2;
    else
        return val1;
}
 
// Function to find the element closest to
// target in divisors vector
int findClosest(vector<int>& arr, int n, int target)
{
    // Corner cases
    if (target <= arr[0])
        return arr[0];
    if (target >= arr[n - 1])
        return arr[n - 1];
 
    // Perform binary search
    int i = 0, j = n, mid = 0;
    while (i < j) {
        mid = (i + j) / 2;
 
        if (arr[mid] == target)
            return arr[mid];
 
        // Check if target is less than the array
        // element then search in left half
        if (target < arr[mid]) {
 
            // Check if target is greater
            // than previous
            // to mid, return closest of two
            if (mid > 0 && target > arr[mid - 1])
                return getClosest(arr[mid - 1], arr[mid],
                                  target);
 
            // Repeat for left half
            j = mid;
        }
 
        // Check if target is greater than mid
        else {
            if (mid < n - 1 && target < arr[mid + 1])
                return getClosest(arr[mid], arr[mid + 1],
                                  target);
            // Update i
            i = mid + 1;
        }
    }
 
    // Only single element left after search
    return arr[mid];
}
 
// Function to print the divisor of N closest to X
void printClosest(int N, int X)
{
    // Function call to calculate and stores
    // divisors of all numbers in a vector
    computeDivisors();
 
    // Stores the closest value to target
    int ans
        = findClosest(divisors[N], divisors[N].size(), X);
 
    // Print the answer
    cout << ans;
}
 
// Driver Code
int main()
{
    // Given N & X
    int N = 16, X = 5;
 
    // Function Call
    printClosest(N, X);
}


Java




// Java program for the above approach
import java.util.*;
class GFG
{
 
// Define macros
static final int MAX = 10000;
static Vector<Integer>[] divisors = new Vector[MAX + 1];
 
// Stores divisors for all numbers
// in the vector divisors
static void computeDivisors()
{
    for (int i = 1; i <= MAX; i++)
    {
        for (int j = i; j <= MAX; j += i)
        {
 
            // i is the divisor and
            // j is the multiple
            divisors[j].add(i);
        }
    }
}
 
// Function to compare the closeness of the given
// target
static int getClosest(int val1, int val2, int target)
{
    if (target - val1 >= val2 - target)
        return val2;
    else
        return val1;
}
 
// Function to find the element closest to
// target in divisors vector
static int findClosest(Vector<Integer> array,
                       int n, int target)
{
    Integer []arr = array.toArray(new Integer[array.size()]);
     
  // Corner cases
    if (target <= arr[0])
        return arr[0];
    if (target >= arr[n - 1])
        return arr[n - 1];
 
    // Perform binary search
    int i = 0, j = n, mid = 0;
    while (i < j)
    {
        mid = (i + j) / 2;
        if (arr[mid] == target)
            return arr[mid];
 
        // Check if target is less than the array
        // element then search in left half
        if (target < arr[mid])
        {
 
            // Check if target is greater
            // than previous
            // to mid, return closest of two
            if (mid > 0 && target > arr[mid - 1])
                return getClosest(arr[mid - 1], arr[mid],
                                  target);
 
            // Repeat for left half
            j = mid;
        }
 
        // Check if target is greater than mid
        else
        {
            if (mid < n - 1 && target < arr[mid + 1])
                return getClosest(arr[mid], arr[mid + 1],
                                  target);
            // Update i
            i = mid + 1;
        }
    }
 
    // Only single element left after search
    return arr[mid];
}
 
// Function to print the divisor of N closest to X
static void printClosest(int N, int X)
{
   
    // Function call to calculate and stores
    // divisors of all numbers in a vector
    computeDivisors();
 
    // Stores the closest value to target
    int ans
        = findClosest(divisors[N], divisors[N].size(), X);
 
    // Print the answer
    System.out.print(ans);
}
 
// Driver Code
public static void main(String[] args)
{
   
    // Given N & X
    int N = 16, X = 5;
    for(int i = 0; i < divisors.length; i++)
        divisors[i] = new Vector<Integer>();
   
    // Function Call
    printClosest(N, X);
}
}
 
// This code is contributed by 29AjayKumar


Python3




# Python3 program for the above approach
MAX = 10000
 
divisors = [[] for i in range(MAX + 1)]
 
# Stores divisors for all numbers
# in the vector divisors
def computeDivisors():
     
    global divisors
    global MAX
     
    for i in range(1, MAX + 1, 1):
        for j in range(i, MAX + 1, i):
             
            # i is the divisor and
            # j is the multiple
            divisors[j].append(i)
 
# Function to compare the closeness of the given
# target
def getClosest(val1, val2, target):
     
    if (target - val1 >= val2 - target):
        return val2
    else:
        return val1
 
# Function to find the element closest to
# target in divisors vector
def findClosest(arr, n, target):
     
    # Corner cases
    if (target <= arr[0]):
        return arr[0]
    if (target >= arr[n - 1]):
        return arr[n - 1]
 
    # Perform binary search
    i = 0
    j = n
    mid = 0
     
    while (i < j):
        mid = (i + j) // 2
 
        if (arr[mid] == target):
            return arr[mid]
 
        # Check if target is less than the array
        # element then search in left half
        if (target < arr[mid]):
 
            # Check if target is greater
            # than previous
            # to mid, return closest of two
            if (mid > 0 and target > arr[mid - 1]):
                return getClosest(arr[mid - 1],
                                  arr[mid],target)
 
            # Repeat for left half
            j = mid
 
        # Check if target is greater than mid
        else:
            if (mid < n - 1 and target < arr[mid + 1]):
                return getClosest(arr[mid],
                                  arr[mid + 1], target)
                 
            # Update i
            i = mid + 1
 
    # Only single element left after search
    return arr[mid]
 
# Function to print the divisor of N closest to X
def printClosest(N, X):
     
    global divisors
     
    # Function call to calculate and stores
    # divisors of all numbers in a vector
    computeDivisors()
 
    # Stores the closest value to target
    ans = findClosest(divisors[N],
                  len(divisors[N]), X)
 
    # Print the answer
    print(ans)
 
# Driver Code
if __name__ == '__main__':
     
    # Given N & X
    N = 16
    X = 5
 
    # Function Call
    printClosest(N, X)
     
# This code is contributed by SURENDRA_GANGWAR


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
 
// Define macros
static readonly int MAX = 10000;
static List<int>[] divisors = new List<int>[MAX + 1];
 
// Stores divisors for all numbers
// in the vector divisors
static void computeDivisors()
{
    for (int i = 1; i <= MAX; i++)
    {
        for (int j = i; j <= MAX; j += i)
        {
 
            // i is the divisor and
            // j is the multiple
            divisors[j].Add(i);
        }
    }
}
 
// Function to compare the closeness of the given
// target
static int getClosest(int val1, int val2, int target)
{
    if (target - val1 >= val2 - target)
        return val2;
    else
        return val1;
}
 
// Function to find the element closest to
// target in divisors vector
static int findClosest(List<int> array,
                       int n, int target)
{
    int []arr = array.ToArray();
     
  // Corner cases
    if (target <= arr[0])
        return arr[0];
    if (target >= arr[n - 1])
        return arr[n - 1];
 
    // Perform binary search
    int i = 0, j = n, mid = 0;
    while (i < j)
    {
        mid = (i + j) / 2;
        if (arr[mid] == target)
            return arr[mid];
 
        // Check if target is less than the array
        // element then search in left half
        if (target < arr[mid])
        {
 
            // Check if target is greater
            // than previous
            // to mid, return closest of two
            if (mid > 0 && target > arr[mid - 1])
                return getClosest(arr[mid - 1], arr[mid],
                                  target);
 
            // Repeat for left half
            j = mid;
        }
 
        // Check if target is greater than mid
        else
        {
            if (mid < n - 1 && target < arr[mid + 1])
                return getClosest(arr[mid], arr[mid + 1],
                                  target);
            // Update i
            i = mid + 1;
        }
    }
 
    // Only single element left after search
    return arr[mid];
}
 
// Function to print the divisor of N closest to X
static void printClosest(int N, int X)
{
   
    // Function call to calculate and stores
    // divisors of all numbers in a vector
    computeDivisors();
 
    // Stores the closest value to target
    int ans
        = findClosest(divisors[N], divisors[N].Count, X);
 
    // Print the answer
    Console.Write(ans);
}
 
// Driver Code
public static void Main(String[] args)
{
   
    // Given N & X
    int N = 16, X = 5;
    for(int i = 0; i < divisors.Length; i++)
        divisors[i] = new List<int>();
   
    // Function Call
    printClosest(N, X);
}
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
 
// Javascript program for the above approach
 
// Define macros
let  MAX = 10000;
 
let divisors = new Array(MAX + 1);
 
// Stores divisors for all numbers
// in the vector divisors
function computeDivisors()
{
    for(let i = 1; i <= MAX; i++)
    {
        for(let j = i; j <= MAX; j += i)
        {
             
            // i is the divisor and
            // j is the multiple
            divisors[j].push(i);
        }
    }
}
 
// Function to compare the closeness of the given
// target
function getClosest(val1, val2, target)
{
    if (target - val1 >= val2 - target)
        return val2;
    else
        return val1;
}
 
// Function to find the element closest to
// target in divisors vector
function findClosest(arr, n, target)
{
     
    // Corner cases
    if (target <= arr[0])
        return arr[0];
    if (target >= arr[n - 1])
        return arr[n - 1];
  
    // Perform binary search
    let i = 0, j = n, mid = 0;
     
    while (i < j)
    {
        mid = Math.floor((i + j) / 2);
        if (arr[mid] == target)
            return arr[mid];
  
        // Check if target is less than the array
        // element then search in left half
        if (target < arr[mid])
        {
  
            // Check if target is greater
            // than previous
            // to mid, return closest of two
            if (mid > 0 && target > arr[mid - 1])
                return getClosest(arr[mid - 1], arr[mid],
                                  target);
  
            // Repeat for left half
            j = mid;
        }
  
        // Check if target is greater than mid
        else
        {
            if (mid < n - 1 && target < arr[mid + 1])
                return getClosest(arr[mid], arr[mid + 1],
                                  target);
                                   
            // Update i
            i = mid + 1;
        }
    }
  
    // Only single element left after search
    return arr[mid];
}
 
// Function to print the divisor of N closest to X
function printClosest(N, X)
{
     
    // Function call to calculate and stores
    // divisors of all numbers in a vector
    computeDivisors();
  
    // Stores the closest value to target
    let ans = findClosest(divisors[N],
                          divisors[N].length, X);
  
    // Print the answer
    document.write(ans);
}
 
// Driver Code
 
// Given N & X
let N = 16, X = 5;
for(let i = 0; i < divisors.length; i++)
    divisors[i] = [];
 
// Function Call
printClosest(N, X);
 
// This code is contributed by unknown2108
 
</script>


Output: 

4

 

Time Complexity: O(N*log(log(N))) 
Auxiliary Space: O(MAX)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads