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++
#include <bits/stdc++.h>
using namespace std;
string changeNtoM( int N, int M)
{
if (N == M) {
return " " ;
}
if (M == 0) {
return "-" ;
}
queue<pair< int , string> > q;
unordered_map< int , bool > visited;
q.push({ N, "" }), visited[N] = 1;
q.push({ 1, "" }), visited[1] = 1;
while (!q.empty()) {
pair< int , string> cur = q.front();
q.pop();
if (cur.first == M) {
return cur.second;
}
if (!visited[cur.first + cur.first]
&& cur.first + cur.first <= M) {
q.push({ cur.first + cur.first,
cur.second + "+" });
visited[cur.first + cur.first] = 1;
}
if (!visited[cur.first * cur.first]
&& cur.first * cur.first <= M) {
q.push({ cur.first * cur.first,
cur.second + "*" });
visited[cur.first * cur.first] = 1;
}
}
return "-1" ;
}
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;
}
|
Java
import java.util.*;
class Main {
static String changeNtoM( int N, int M)
{
if (N == M) {
return " " ;
}
if (M == 0 ) {
return "-" ;
}
Queue<Map.Entry<Integer, String>> q = new LinkedList<>();
Map<Integer, Boolean> visited = new HashMap<>();
q.add( new AbstractMap.SimpleEntry<>(N, "" ));
visited.put(N, true );
q.add( new AbstractMap.SimpleEntry<>( 1 , "" ));
visited.put( 1 , true );
while (!q.isEmpty()) {
Map.Entry<Integer, String> cur = q.poll();
if (cur.getKey() == M) {
return cur.getValue();
}
if (!visited.containsKey(cur.getKey() + cur.getKey())
&& cur.getKey() + cur.getKey() <= M) {
q.add( new AbstractMap.SimpleEntry<>(cur.getKey() + cur.getKey(),
cur.getValue() + "+" ));
visited.put(cur.getKey() + cur.getKey(), true );
}
if (!visited.containsKey(cur.getKey() * cur.getKey())
&& cur.getKey() * cur.getKey() <= M) {
q.add( new AbstractMap.SimpleEntry<>(cur.getKey() * cur.getKey(),
cur.getValue() + "*" ));
visited.put(cur.getKey() * cur.getKey(), true );
}
}
return "-1" ;
}
public static void main(String[] args) {
int N = 7 , M = 392 ;
String result = changeNtoM(N, M);
if (result.equals( "-1" ))
System.out.println(result);
else
System.out.println(result.length() + "\n" + result);
}
}
|
Python
def changeNtoM(N, M):
if N = = M:
return " "
if M = = 0 :
return "-"
q = []
visited = {}
q.append([N, ""])
visited[N] = 1
q.append([ 1 , "" ])
visited[ 1 ] = 1
while len (q) > 0 :
cur = q.pop( 0 )
if cur[ 0 ] = = M:
return cur[ 1 ]
if ( 2 * cur[ 0 ]) not in visited and 2 * cur[ 0 ] < = M:
q.append([ 2 * cur[ 0 ], cur[ 1 ] + "+" ])
visited[ 2 * cur[ 0 ]] = 1
if (cur[ 0 ] * cur[ 0 ]) not in visited and cur[ 0 ] * cur[ 0 ] < = M:
q.append([cur[ 0 ] * cur[ 0 ], cur[ 1 ] + "*" ])
visited[cur[ 0 ] * cur[ 0 ]] = 1
return "-1"
N = 7
M = 392
result = changeNtoM(N, M)
if result = = "-1" :
print (result)
else :
print ( len (result))
print (result)
|
C#
using System;
using System.Collections.Generic;
class MainClass {
static string changeNtoM( int N, int M)
{
if (N == M) {
return " " ;
}
if (M == 0) {
return "-" ;
}
Queue<KeyValuePair< int , string > > q
= new Queue<KeyValuePair< int , string > >();
Dictionary< int , bool > visited
= new Dictionary< int , bool >();
q.Enqueue( new KeyValuePair< int , string >(N, "" ));
visited[N] = true ;
q.Enqueue( new KeyValuePair< int , string >(1, "" ));
visited[1] = true ;
while (q.Count > 0) {
KeyValuePair< int , string > cur = q.Dequeue();
if (cur.Key == M) {
return cur.Value;
}
if (!visited.ContainsKey(cur.Key + cur.Key)
&& cur.Key + cur.Key <= M) {
q.Enqueue( new KeyValuePair< int , string >(
cur.Key + cur.Key, cur.Value + "+" ));
visited[cur.Key + cur.Key] = true ;
}
if (!visited.ContainsKey(cur.Key * cur.Key)
&& cur.Key * cur.Key <= M) {
q.Enqueue( new KeyValuePair< int , string >(
cur.Key * cur.Key, cur.Value + "*" ));
visited[cur.Key * cur.Key] = true ;
}
}
return "-1" ;
}
public static void Main( string [] args)
{
int N = 7, M = 392;
string result = changeNtoM(N, M);
if (result == "-1" )
Console.WriteLine(result);
else
Console.WriteLine(result.Length + "\n"
+ result);
}
}
|
Javascript
function changeNtoM(N, M)
{
if (N == M) {
return " " ;
}
if (M == 0) {
return "-" ;
}
let q = [];
let visited = new Map();
q.push([N, "" ]);
visited.set(N, 1);
q.push([1, "" ]);
visited.set(1, 1);
while (q.length > 0) {
let cur = q.shift();
if (cur[0] == M) {
return cur[1];
}
if (!visited.has((2*cur[0])) && 2*cur[0]<= M) {
q.push([2*cur[0], cur[1] + "+" ]);
visited.set((cur[0] + cur[0]), 1);
}
if (!visited.has((cur[0]* cur[0])) && cur[0] * cur[0] <= M) {
q.push([cur[0] * cur[0], cur[1] + "*" ]);
visited.set((cur[0]* cur[0]), 1);
}
}
return "-1" ;
}
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);
}
|
Time Complexity: O(min(2log2(M – N), M – N)) Auxiliary Space: O((M-N)* log2(M – N))
|