Minimize steps required to convert number N to M using arithmetic operators
Given two integers N and M, the task is to find the sequence of the minimum number of operations required to convert the number N into M such that in each operation N can be added (N = N + N), subtracted as (N = N – N), multiplied as (N = N*N), or divided as (N = N/N). If it is not possible to convert N into M then print “-1”.
Examples:
Input: N = 7, M = 392
Output: 3
+, *, +
Explanation:
Following are the operations performed:
- Performing addition modifies the value of N as 7 + 7 = 14.
- Performing multiplication modifies the value of N as 14*14 = 196.
- Performing addition modifies the value of N as 196 + 196 = 392.
After the above sequence of moves as “+*+”, the value of N can be modified to M.
Input: N = 7, M = 9
Output: -1
Explanation: There are no possible sequence of operations to convert N to M.
Approach: The given problem can be solved using the following observations:
- Subtraction operation will always result in 0 as N = N – N = 0. Similarly, division operation will always result in 1 as N = N / N = 1. Therefore, these cases can be handled easily.
- For addition and multiplication, the problem can be solved using a Breadth-First Search Traversal by creating a state for each of the sequences of operations in increasing order of operation count.
The steps to solve the given problem are as follows:
- Maintain a queue to store the BFS states where each state contains the current reachable integer N’ and a string representing the sequence of operations to reach N’ from N.
- Initially, add a state {N, “”} representing N and sequence of operations as empty into the queue.
- Add a state {1, “/”} for the division operation into the queue as well.
- During the Breadth-First traversal, for each state, add two states where the 1st state will represent addition (N’ + N’) and the 2nd state will represent multiplication (N’ * N’).
- Maintain an unordered map to check whether the current state is already visited during the BFS Traversal.
- If the value of the current state is equal to M, then the sequence of operations obtained till M is the result. Otherwise, print “-1”.
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 sequence of // minimum number of operations needed // to convert N into M using +, -, *, / string changeNtoM( int N, int M) { // Case where N and M are same if (N == M) { return " " ; } // Case where M = 0 if (M == 0) { return "-" ; } // Stores the BFS states in a queue queue<pair< int , string> > q; // Stores if current state is visited unordered_map< int , bool > visited; // Initial State q.push({ N, "" }), visited[N] = 1; // State where the first operation is / q.push({ 1, "/" }), visited[1] = 1; // Loop for the BFS traversal while (!q.empty()) { // Stores the current BFS state pair< int , string> cur = q.front(); q.pop(); // If the value of current state is // equal to M return the stored // sequence of operations if (cur.first == M) { // Return answer return cur.second; } // Adding 1st state representing the // addition operation(N' + N') if (!visited[cur.first + cur.first] && cur.first + cur.first <= M) { // Add state into queue and // mark the state visited q.push({ cur.first + cur.first, cur.second + "+" }); visited[cur.first + cur.first] = 1; } // Adding 2nd state representing the // multiplication operation(N' * N') if (!visited[cur.first * cur.first] && cur.first * cur.first <= M) { // Add state into queue and // mark the state visited q.push({ cur.first * cur.first, cur.second + "*" }); visited[cur.first * cur.first] = 1; } } // No valid sequence of operations exist return "-1" ; } // Driver Code int main() { int N = 7, M = 392; string result = changeNtoM(N, M); if (result == "-1" ) cout << result << endl; else cout << result.length() << endl << result; return 0; } |
Javascript
// JavaScript program for the above approach // Function to find the sequence of // minimum number of operations needed // to convert N into M using +, -, *, / function changeNtoM(N, M) { // Case where N and M are same if (N == M) { return " " ; } // Case where M = 0 if (M == 0) { return "-" ; } // Stores the BFS states in a queue let q = []; // Stores if current state is visited let visited = new Map(); // Initial State q.push([N, "" ]); visited.set(N, 1); // State where the first operation is / q.push([1, "/" ]); visited.set(1, 1); // Loop for the BFS traversal while (q.length > 0) { // Stores the current BFS state let cur = q.shift(); // If the value of current state is // equal to M return the stored // sequence of operations if (cur[0] == M) { // Return answer return cur[1]; } // Adding 1st state representing the // addition operation(N' + N') if (!visited.has((2*cur[0])) && 2*cur[0]<= M) { // Add state into queue and // mark the state visited q.push([2*cur[0], cur[1] + "+" ]); visited.set((cur[0] + cur[0]), 1); } // Adding 2nd state representing the // multiplication operation(N' * N') if (!visited.has((cur[0]* cur[0])) && cur[0] * cur[0] <= M) { // Add state into queue and // mark the state visited q.push([cur[0] * cur[0], cur[1] + "*" ]); visited.set((cur[0]* cur[0]), 1); } } // No valid sequence of operations exist return "-1" ; } // Driver Code let N = 7; let M = 392; let result = changeNtoM(N, M); if (result == "-1" ) console.log(result); else { console.log(result.length); console.log(result); } // The code is contributed by Nidhi goel |
3 +*+
Time Complexity: O(min(2log2(M – N), M – N))
Auxiliary Space: O((M-N)* log2(M – N))