Open In App

Count of prime factors of N to be added at each step to convert N to M

Improve
Improve
Like Article
Like
Save
Share
Report

Given two integers N and M, the task is to find out smallest number of operations required to convert N to M. Each operation involves adding one of the prime factors of the current value of N. If it is possible to obtain M, print the number of operations. Otherwise, print -1.

Examples: 

Input: N = 6, M = 10 
Output:
Explanation: 
Prime factors of 6 are [2, 3]. 
Adding 2 to N, we obtain 8. 
The prime factor of 8 is [2]. 
Adding 2 to N, we obtain 10, which is the desired result. 
Hence, total steps = 2

Input: N = 2, M = 3 
Output: -1 
Explanation: 
There is no way to convert N = 2 to M = 3. 

Approach: 
The problem can be solved by using BFS to obtain minimum steps to reach M and Sieve of Eratosthenes to precompute prime numbers. 
Follow the steps below to solve the problem: 

  • Store and precompute all prime numbers using Sieve.
  • Now, if N is already equal to M, print 0 as no addition operation is required.
  • Visualize this problem as a graph problem to perform BFS. At each level store the reachable numbers from the values of N in the previous level by adding prime factors.
  • Now, start by inserting (N, 0), where N denotes the value and 0 denotes the number of operations to reach that value, in the queue initially.
  • At each level of the queue, traverse all elements one by one by extracting the element at the front() and perform the following: 
    1. Store q.front().first() in newNum and q.front().second() in distance, where newNum is the current value and distance is the number of operations required to reach this value.
    2. Store all prime factors of newNum in a set.
    3. If newNum is equal to M, then print distance, as it is the minimum operations required.
    4. If newNum is greater than M, then break.
    5. Otherwise, newNum is less than M. So, update newNum by adding its prime factors i one by one and store (newNum + i, distance + 1) in the queue and repeat the above steps for the next level.
  • If the search continues to a level where the queue becomes empty, it means that M cannot be obtained from N. Print -1.

Below is the implementation of the above approach: 

C++




// C++ program to find the minimum
// steps required to convert a number
// N to M.
#include <bits/stdc++.h>
using namespace std;
 
// Array to store shortest prime
// factor of every integer
int spf[100009];
 
// Function to precompute
// shortest prime factors
void sieve()
{
    memset(spf, -1, 100005);
    for (int i = 2; i * i <= 100005; i++) {
        for (int j = i; j <= 100005; j += i) {
            if (spf[j] == -1) {
                spf[j] = i;
            }
        }
    }
}
 
// Function to insert distinct prime factors
// of every integer into a set
set<int> findPrimeFactors(set<int> s,
                          int n)
{
    // Store distinct prime
    // factors
    while (n > 1) {
        s.insert(spf[n]);
        n /= spf[n];
    }
    return s;
}
 
// Function to return minimum
// steps using BFS
int MinimumSteps(int n, int m)
{
 
    // Queue of pairs to store
    // the current number and
    // distance from root.
    queue<pair<int, int> > q;
 
    // Set to store distinct
    // prime factors
    set<int> s;
 
    // Run BFS
    q.push({ n, 0 });
    while (!q.empty()) {
 
        int newNum = q.front().first;
        int distance = q.front().second;
 
        q.pop();
 
        // Find out the prime factors of newNum
        set<int> k = findPrimeFactors(s,
                                      newNum);
 
        // Iterate over every prime
        // factor of newNum.
        for (auto i : k) {
 
            // If M is obtained
            if (newNum == m) {
 
                // Return number of
                // operations
                return distance;
            }
 
            // If M is exceeded
            else if (newNum > m) {
                break;
            }
 
            // Otherwise
            else {
 
                // Update and store the new
                // number obtained by prime factor
                q.push({ newNum + i,
                         distance + 1 });
            }
        }
    }
 
    // If M cannot be obtained
    return -1;
}
 
// Driver code
int main()
{
    int N = 7, M = 16;
 
    sieve();
 
    cout << MinimumSteps(N, M);
}


Java




// Java program to find the minimum
// steps required to convert a number
// N to M.
import java.util.*;
 
class GFG{
     
static class pair
{
    int first, second;
     
    public pair(int first, int second) 
    {
        this.first = first;
        this.second = second;
    }   
}
 
// Array to store shortest prime
// factor of every integer
static int []spf = new int[100009];
 
// Function to precompute
// shortest prime factors
static void sieve()
{
    for(int i = 0; i < 100005; i++)
        spf[i] = -1;
         
    for(int i = 2; i * i <= 100005; i++)
    {
        for(int j = i; j <= 100005; j += i)
        {
            if (spf[j] == -1)
            {
                spf[j] = i;
            }
        }
    }
}
 
// Function to insert distinct prime factors
// of every integer into a set
static HashSet<Integer> findPrimeFactors(HashSet<Integer> s,
                                         int n)
{
     
    // Store distinct prime
    // factors
    while (n > 1)
    {
        s.add(spf[n]);
        n /= spf[n];
    }
    return s;
}
 
// Function to return minimum
// steps using BFS
static int MinimumSteps(int n, int m)
{
 
    // Queue of pairs to store
    // the current number and
    // distance from root.
    Queue<pair > q = new LinkedList<>();
 
    // Set to store distinct
    // prime factors
    HashSet<Integer> s = new HashSet<Integer>();
 
    // Run BFS
    q.add(new pair(n, 0));
     
    while (!q.isEmpty())
    {
        int newNum = q.peek().first;
        int distance = q.peek().second;
 
        q.remove();
 
        // Find out the prime factors of newNum
        HashSet<Integer> k = findPrimeFactors(s,
                                      newNum);
 
        // Iterate over every prime
        // factor of newNum.
        for(int i : k)
        {
             
            // If M is obtained
            if (newNum == m)
            {
 
                // Return number of
                // operations
                return distance;
            }
 
            // If M is exceeded
            else if (newNum > m)
            {
                break;
            }
 
            // Otherwise
            else
            {
                 
                // Update and store the new
                // number obtained by prime factor
                q.add(new pair(newNum + i,
                             distance + 1 ));
            }
        }
    }
 
    // If M cannot be obtained
    return -1;
}
 
// Driver code
public static void main(String[] args)
{
    int N = 7, M = 16;
 
    sieve();
 
    System.out.print(MinimumSteps(N, M));
}
}
 
// This code is contributed by Amit Katiyar


Python3




# Python3 program to find the minimum
# steps required to convert a number
# N to M.
  
# Array to store shortest prime
# factor of every integer
spf = [-1 for i in range(100009)];
  
# Function to precompute
# shortest prime factors
def sieve():
 
    i=2
     
    while(i * i <= 100006):
        for j in range(i, 100006, i):
            if (spf[j] == -1):
                spf[j] = i;
        i += 1
         
# Function to append distinct prime factors
# of every integer into a set
def findPrimeFactors(s, n):
 
    # Store distinct prime
    # factors
    while (n > 1):
        s.add(spf[n]);
        n //= spf[n];
     
    return s;
 
# Function to return minimum
# steps using BFS
def MinimumSteps( n, m):
  
    # Queue of pairs to store
    # the current number and
    # distance from root.
    q = []
  
    # Set to store distinct
    # prime factors
    s = set()
  
    # Run BFS
    q.append([ n, 0 ])
     
    while (len(q) != 0):
  
        newNum = q[0][0]
        distance = q[0][1]
 
        q.pop(0);
  
        # Find out the prime factors of newNum
        k = findPrimeFactors(s, newNum);
  
        # Iterate over every prime
        # factor of newNum.
        for i in k:
  
            # If M is obtained
            if (newNum == m):
  
                # Return number of
                # operations
                return distance;
  
            # If M is exceeded
            elif (newNum > m):
                break;
  
            # Otherwise
            else:
  
                # Update and store the new
                # number obtained by prime factor
                q.append([ newNum + i, distance + 1 ]);
             
    # If M cannot be obtained
    return -1;
 
# Driver code
if __name__=='__main__':
 
    N = 7
    M = 16;
  
    sieve();
  
    print( MinimumSteps(N, M))
 
  # This code is contributed by rutvik_56


C#




// C# program to find the minimum
// steps required to convert a number
// N to M.
using System;
using System.Collections.Generic;
 
class GFG{
     
class pair
{
    public int first, second;
     
    public pair(int first, int second) 
    {
        this.first = first;
        this.second = second;
    }   
}
 
// Array to store shortest prime
// factor of every integer
static int []spf = new int[100009];
 
// Function to precompute
// shortest prime factors
static void sieve()
{
    for(int i = 0; i < 100005; i++)
        spf[i] = -1;
         
    for(int i = 2; i * i <= 100005; i++)
    {
        for(int j = i; j <= 100005; j += i)
        {
            if (spf[j] == -1)
            {
                spf[j] = i;
            }
        }
    }
}
 
// Function to insert distinct prime factors
// of every integer into a set
static HashSet<int> findPrimeFactors(HashSet<int> s,
                                             int n)
{
     
    // Store distinct prime
    // factors
    while (n > 1)
    {
        s.Add(spf[n]);
        n /= spf[n];
    }
    return s;
}
 
// Function to return minimum
// steps using BFS
static int MinimumSteps(int n, int m)
{
     
    // Queue of pairs to store
    // the current number and
    // distance from root.
    Queue<pair> q = new Queue<pair>();
 
    // Set to store distinct
    // prime factors
    HashSet<int> s = new HashSet<int>();
 
    // Run BFS
    q.Enqueue(new pair(n, 0));
     
    while (q.Count != 0)
    {
        int newNum = q.Peek().first;
        int distance = q.Peek().second;
 
        q.Dequeue();
 
        // Find out the prime factors of newNum
        HashSet<int> k = findPrimeFactors(s,
                                          newNum);
 
        // Iterate over every prime
        // factor of newNum.
        foreach(int i in k)
        {
             
            // If M is obtained
            if (newNum == m)
            {
 
                // Return number of
                // operations
                return distance;
            }
 
            // If M is exceeded
            else if (newNum > m)
            {
                break;
            }
 
            // Otherwise
            else
            {
                 
                // Update and store the new
                // number obtained by prime factor
                q.Enqueue(new pair(newNum + i,
                                 distance + 1));
            }
        }
    }
 
    // If M cannot be obtained
    return -1;
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 7, M = 16;
 
    sieve();
 
    Console.Write(MinimumSteps(N, M));
}
}
 
// This code is contributed by Princi Singh


Javascript




<script>
 
// JavaScript program to find the minimum
// steps required to convert a number
// N to M.
     
class pair
{
    constructor(first, second)
    {
        this.first = first;
        this.second = second;
    }
}
 
// Array to store shortest prime
// factor of every integer
var spf = Array(100009).fill(0);
 
// Function to precompute
// shortest prime factors
function sieve()
{
    for(var i = 0; i < 100005; i++)
        spf[i] = -1;
         
    for(var i = 2; i * i <= 100005; i++)
    {
        for(var j = i; j <= 100005; j += i)
        {
            if (spf[j] == -1)
            {
                spf[j] = i;
            }
        }
    }
}
 
// Function to insert distinct prime factors
// of every integer into a set
function findPrimeFactors(s, n)
{
     
    // Store distinct prime
    // factors
    while (n > 1)
    {
        s.add(spf[n]);
        n /= spf[n];
    }
    return s;
}
 
// Function to return minimum
// steps using BFS
function MinimumSteps(n, m)
{
     
    // Queue of pairs to store
    // the current number and
    // distance from root.
    var q = [];
 
    // Set to store distinct
    // prime factors
    var s = new Set();
 
    // Run BFS
    q.push(new pair(n, 0));
     
    while (q.length != 0)
    {
        var newNum = q[0].first;
        var distance = q[0].second;
 
        q.shift();
 
        // Find out the prime factors of newNum
        var k = findPrimeFactors(s,
                                          newNum);
 
        // Iterate over every prime
        // factor of newNum.
        for(var i of k)
        {
             
            // If M is obtained
            if (newNum == m)
            {
 
                // Return number of
                // operations
                return distance;
            }
 
            // If M is exceeded
            else if (newNum > m)
            {
                break;
            }
 
            // Otherwise
            else
            {
                 
                // Update and store the new
                // number obtained by prime factor
                q.push(new pair(newNum + i,
                                 distance + 1));
            }
        }
    }
 
    // If M cannot be obtained
    return -1;
}
 
// Driver code
var N = 7, M = 16;
sieve();
document.write(MinimumSteps(N, M));
 
 
</script>


Output: 

2

 

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



Last Updated : 30 Jun, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads