Skip to content
Related Articles

Related Articles

Improve Article

Minimum number of moves to make M and N equal by repeatedly adding any divisor of number to itself except 1 and the number

  • Last Updated : 02 Aug, 2021

Given two numbers N and M, the task is to find the minimum number of moves to change N to M or -1 if it’s impossible. In one move, add to the current number any of its divisors not equal to 1 and the number itself.

Examples:

Input: N = 4, M = 24
Output: 5
Explanation: the number 24 can be reached starting from 4 using 5 operations: 4->6->8->12->18->24.

Input: N = 4, M = 576
Output: 14

Approach: Build a graph where vertices are numbers from N to M and there is an edge from vertex v1 to vertex v2 if v2 can be obtained from v1 using exactly one operation from the problem statement. To solve the problem, find the shortest path from vertex N to vertex M in this graph. This can be done using the breadth first search algorithm. Follow the steps below to solve the problem: 



  • Initialize a boolean array visited[] to store whether a particular number is counted or not.
  • Fill all the indices of the bool array visited[] with the value false and set the value of visited[N] to true.
  • Initialize a queue of pairs q to store the number visited and the number of operations done.
  • Push the pair {N, 0} into the queue of pairs q.
  • Iterate in a range till the queue of pairs q is not empty.
    • Initialize the variables aux as the first value of the front pair of the queue q and cont as the second value of the front pair of the queue q.
    • Pop the front pair from the queue of pairs q.
    • If aux is equal to M, then, return the value of cont.
    • Iterate in a range [2, aux1/2] and perform the following steps.
      • If i is a factor of aux, then take the following steps.
        • If aux+i is less than equal to M and visited[i+aux] is false, then set the value of visited[aux+i] to true and push the pair {aux+i, cont+1} into the queue of pairs q.
        • If aux+aux/i is less than equal to M and visited[aux/i+aux] is false, then set the value of visited[aux+aux/i] to true and push the pair {aux+aux/i, cont+1} into the queue of pairs q.
  • Return -1 as it is impossible to make N equal to M.

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 minimum number
// of moves to make N and M equal.
int countOperations(int N, int M)
{
    // Array to maintain the numbers
    // included.
    bool visited[100001];
    fill(visited, visited + 100001, false);
 
    // pair of vertex, count
    queue<pair<int, int> > Q;
    Q.push(make_pair(N, 0));
    visited[N] = true;
 
    // run bfs from N
    while (!Q.empty()) {
        int aux = Q.front().first;
        int cont = Q.front().second;
        Q.pop();
 
        // if we reached goal
        if (aux == M)
            return cont;
 
        // Iterate in the range
        for (int i = 2; i * i <= aux; i++)
            // If i is a factor of aux
            if (aux % i == 0) {
                // If i is less than M-aux and
                // is not included earlier.
                if (aux + i <= M && !visited[aux + i]) {
                    Q.push(make_pair(aux + i, cont + 1));
                    visited[aux + i] = true;
                }
                // If aux/i is less than M-aux and
                // is not included earlier.
                if (aux + aux / i <= M
                    && !visited[aux + aux / i]) {
                    Q.push(
                        make_pair(aux + aux / i, cont + 1));
                    visited[aux + aux / i] = true;
                }
            }
    }
 
    // Not possible
    return -1;
}
 
// Driver Code
int main()
{
 
    int N = 4, M = 24;
 
    cout << countOperations(N, M);
 
    return 0;
}

Java




// Java program for above approach
import java.util.*;
 
class GFG{
     
static class pair<T, V>
{
    T first;
    V second;
}
 
static pair<Integer, Integer> make_pair(int f, int s)
{
    pair<Integer, Integer> p = new pair<>();
    p.first = f; p.second = s;
    return p;
}
 
// Function to find the minimum number
// of moves to make N and M equal.
static int countOperations(int N, int M)
{
     
    // Array to maintain the numbers
    // included.
    boolean[] visited = new boolean[100001];
    Arrays.fill(visited, false);
 
    // Pair of vertex, count
    Queue<pair<Integer, Integer>> Q = new LinkedList<>();
    Q.add(make_pair(N, 0));
    visited[N] = true;
 
    // Run bfs from N
    while (!Q.isEmpty())
    {
        int aux = Q.peek().first;
        int cont = Q.peek().second;
        Q.remove();
 
        // If we reached goal
        if (aux == M)
            return cont;
 
        // Iterate in the range
        for(int i = 2; i * i <= aux; i++)
         
            // If i is a factor of aux
            if (aux % i == 0)
            {
                 
                // If i is less than M-aux and
                // is not included earlier.
                if (aux + i <= M && !visited[aux + i])
                {
                    Q.add(make_pair(aux + i, cont + 1));
                    visited[aux + i] = true;
                }
                 
                // If aux/i is less than M-aux and
                // is not included earlier.
                if (aux + aux / i <= M &&
                    !visited[aux + aux / i])
                {
                    Q.add(make_pair(aux + aux / i,
                                   cont + 1));
                    visited[aux + aux / i] = true;
                }
            }
    }
     
    // Not possible
    return -1;
}
 
// Driver Code
public static void main(String[] args)
{
    int N = 4, M = 24;
     
    System.out.println(countOperations(N, M));
}
}
 
// This code is contributed by hritikrommie

Python3




# Python3 program for the above approach.
 
# Function to find the minimum number
# of moves to make N and M equal.
def countOperations(N, M):
  
    # Array to maintain the numbers
    # included.
    visited = [False] * (100001)
    
    # Pair of vertex, count
    Q = []
    Q.append([N, 0])
    visited[N] = True
      
    # Run bfs from N
    while (len(Q) > 0):
        aux = Q[0][0]
        cont = Q[0][1]
        Q.pop(0)
    
        # If we reached goal
        if (aux == M):
            return cont
    
        # Iterate in the range
        i = 2
         
        while i * i <= aux:
             
            # If i is a factor of aux
            if (aux % i == 0):
                 
                # If i is less than M-aux and
                # is not included earlier.
                if (aux + i <= M and not visited[aux + i]):
                    Q.append([aux + i, cont + 1])
                    visited[aux + i] = True
                 
                # If aux/i is less than M-aux and
                # is not included earlier.
                if (aux + int(aux / i) <= M and not
                    visited[aux + int(aux / i)]):
                    Q.append([aux + int(aux / i), cont + 1])
                    visited[aux + int(aux / i)] = True
                     
            i += 1
    
    # Not possible
    return -1
 
# Driver code
N, M = 4, 24
  
print(countOperations(N, M))
 
# This code is contributed by mukesh07

C#




// C# program for the above approach.
using System;
using System.Collections;
class GFG
{
     
    // Function to find the minimum number
    // of moves to make N and M equal.
    static int countOperations(int N, int M)
    {
        // Array to maintain the numbers
        // included.
        bool[] visited = new bool[100001];
      
        // pair of vertex, count
        Queue Q = new Queue();
        Q.Enqueue(new Tuple<int, int>(N, 0));
        visited[N] = true;
        // run bfs from N
        while (Q.Count > 0) {
            int aux = ((Tuple<int,int>)(Q.Peek())).Item1;
            int cont = ((Tuple<int,int>)(Q.Peek())).Item2;
            Q.Dequeue();
      
            // if we reached goal
            if (aux == M)
                return cont;
      
            // Iterate in the range
            for (int i = 2; i * i <= aux; i++)
               
                // If i is a factor of aux
                if (aux % i == 0)
                {
                   
                    // If i is less than M-aux and
                    // is not included earlier.
                    if (aux + i <= M && !visited[aux + i]) {
                        Q.Enqueue(new Tuple<int, int>(aux + i, cont + 1));
                        visited[aux + i] = true;
                    }
                   
                    // If aux/i is less than M-aux and
                    // is not included earlier.
                    if (aux + aux / i <= M
                        && !visited[aux + aux / i]) {
                        Q.Enqueue(new Tuple<int, int>(aux + aux / i, cont + 1));
                        visited[aux + aux / i] = true;
                    }
                }
        }
      
        // Not possible
        return -1;
    }
     
  static void Main ()
  {
    int N = 4, M = 24;
  
    Console.WriteLine(countOperations(N, M));
  }
}
 
// This code is contributed by suresh07.

Javascript




<script>
    // Javascript program for the above approach.
     
    // Function to find the minimum number
    // of moves to make N and M equal.
    function countOperations(N, M)
    {
     
        // Array to maintain the numbers
        // included.
        let visited = new Array(100001);
       
        // pair of vertex, count
        let Q = [];
        Q.push([N, 0]);
        visited[N] = true;
         
        // run bfs from N
        while (Q.length > 0) {
            let aux = Q[0][0];
            let cont = Q[0][1];
            Q.shift();
       
            // if we reached goal
            if (aux == M)
                return cont;
       
            // Iterate in the range
            for (let i = 2; i * i <= aux; i++)
                
                // If i is a factor of aux
                if (aux % i == 0)
                {
                    
                    // If i is less than M-aux and
                    // is not included earlier.
                    if (aux + i <= M && !visited[aux + i]) {
                        Q.push([aux + i, cont + 1]);
                        visited[aux + i] = true;
                    }
                    
                    // If aux/i is less than M-aux and
                    // is not included earlier.
                    if (aux + parseInt(aux / i, 10) <= M
                        && !visited[aux + parseInt(aux / i, 10)]) {
                        Q.push([aux + parseInt(aux / i, 10), cont + 1]);
                        visited[aux + parseInt(aux / i, 10)] = true;
                    }
                }
        }
       
        // Not possible
        return -1;
    }
     
    let N = 4, M = 24;
   
    document.write(countOperations(N, M));
 
// This code is contributed by rameshtravel07.
</script>
Output
5

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

 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.




My Personal Notes arrow_drop_up
Recommended Articles
Page :