Minimum cost to convert 1 to N by multiplying X or right rotation of digits
Given two integers N and X, the task is to convert 1 to N using minimum operations of any of the following operations:
- Change a number (say T) into T*X. This costs one unit.
- Right rotate the number. This costs one unit.
Note: Right rotation means the last digit of the number becomes the first and all other digits get shifted rightwards. For example, 456 becomes 645. The right-shuffle operation cannot be done on single-digit integers or integers which are a multiple of 10.
Examples:
Input: N = 61, X =4
Output: 3
Explanation: The sequence of operations is as follows :
- 1 -> 4 (Using first operation -> T*X= 1 * 4 = 4) cost = 1
- 4 -> 16 (Using first operation -> T*X = 4 * 4 = 16) cost = 1
- 16 -> 61 (Using second operation -> right shuffling 16 -> 61) cost = 1
Hence, the minimum costs required to convert from initial 1 to N is 3.
Input: N = 72, X = 3
Output: 4
Explanation: The sequence of operations is as follows :
- 1 -> 3 (Using first operation -> T*X = 1*3 = 3 ) cost = 1
- 3 -> 9 (Using first operation -> T*X = 3*3 = 9) cost = 1
- 9 -> 27 (Using first operation -> T*X = 9*3 = 27) cost = 1
- 27 -> 72 (Using second operation -> right shuffling 27 -> 72) cost = 1
Hence, the minimum cost required to convert from initial 1 to N is 4.
Input: N = 5, X = 3
Output: -1
Explanation: It is impossible to reach 5.
Naive Approach: The naive approach is to try all possible combinations by performing the operations.
It can be observed that the upper limit of required operations does not exceed value N. So generate all possible values that can be formed using i operations (i in range [1, N]) and check if any of them is equal to N and update the minimum cost accordingly
Look here to generate all the possible combinations of T operations. Follow the below steps to solve this problem:
- Iterate a loop from T = 1 to N
- Iterate over all 2T combinations of possible numbers using T moves (2T because either perform type 1 or type 2 operation).
- Assign temp = 1 to store the number formed
- If the first operation is not performed
- Else, if temp > 0 and temp is not a multiple of 10
- If temp = N, then return T because that is the minimum cost.
- If it is not possible to form the number within N steps then it cannot be formed (as mentioned earlier), so return -1.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
long long right_shuffle( long long t)
{
auto str = to_string(t);
rotate(str.begin(), str.begin()
+ str.size() - 1, str.end());
return stoll(str);
}
int minimumCoins( int n, int x)
{
for ( int t = 1; t <= n; ++t) {
for ( int mask = 0; mask < (1LL << t);
++mask) {
long long temp = 1;
for ( int i = 0; i < t; ++i) {
if (!(mask & (1LL << i))) {
temp = temp * x;
}
else {
if (temp <= 10
|| temp % 10 == 0)
temp = temp * x;
else
temp = right_shuffle(temp);
}
}
if (temp == n)
return t;
}
}
return -1;
}
int main()
{
int N = 61, X = 4;
cout << minimumCoins(N, X);
return 0;
}
|
Java
class GFG
{
static int right_shuffle( int num)
{
int rev_num = 0 ;
while (num > 0 )
{
rev_num = rev_num * 10 + num % 10 ;
num = num / 10 ;
}
return rev_num;
}
static int minimumCoins( int n, int x)
{
for ( int t = 1 ; t <= n; ++t) {
for ( int mask = 0 ; mask < ( 1 << t);
++mask) {
int temp = 1 ;
for ( int i = 0 ; i < t; ++i) {
if ((mask & ( 1 << i)) == 0 ) {
temp = temp * x;
}
else {
if (temp <= 10
|| temp % 10 == 0 )
temp = temp * x;
else
temp = right_shuffle(temp);
}
}
if (temp == n)
return t;
}
}
return - 1 ;
}
public static void main(String args[]) {
int N = 61 , X = 4 ;
System.out.print(minimumCoins(N, X));
}
}
|
Python3
def right_shuffle(t):
stri = str (t)
stri = stri[ len (stri) - 1 ] + stri[: - 1 ]
return int (stri)
def minimumCoins(n, x):
for t in range ( 1 , n + 1 ):
for mask in range ( 0 , 1 << t):
temp = 1
for i in range ( 0 , t):
if ( not (mask & ( 1 << i))):
temp = temp * x
else :
if (temp < = 10
or temp % 10 = = 0 ):
temp = temp * x
else :
temp = right_shuffle(temp)
if (temp = = n):
return t
return - 1
if __name__ = = "__main__" :
N, X = 61 , 4
print (minimumCoins(N, X))
|
C#
using System;
class GFG {
static int right_shuffle( int num)
{
int rev_num = 0;
while (num > 0) {
rev_num = rev_num * 10 + num % 10;
num = num / 10;
}
return rev_num;
}
static int minimumCoins( int n, int x)
{
for ( int t = 1; t <= n; ++t) {
for ( int mask = 0; mask < (1 << t); ++mask) {
int temp = 1;
for ( int i = 0; i < t; ++i) {
if ((mask & (1 << i)) == 0) {
temp = temp * x;
}
else {
if (temp <= 10 || temp % 10 == 0)
temp = temp * x;
else
temp = right_shuffle(temp);
}
}
if (temp == n)
return t;
}
}
return -1;
}
public static void Main( string [] args)
{
int N = 61, X = 4;
Console.WriteLine(minimumCoins(N, X));
}
}
|
Javascript
function right_shuffle(t)
{
var stri = t.toString();
stri = stri[stri.length - 1] + stri.substring(0, stri.length - 1);
return parseInt(stri);
}
function minimumCoins(n, x)
{
for ( var t = 1; t <= n; t++)
{
for ( var mask = 0; mask < (1 << t); mask++)
{
var temp = 1;
for ( var i = 0; i < t; i++)
{
if (!(mask & (1 << i)))
{
temp = temp * x;
}
else
{
if (temp <= 10 || temp % 10 == 0)
temp = temp * x;
else
temp = right_shuffle(temp);
}
}
if (temp == n)
return t;
}
}
return -1;
}
var N = 61;
var X = 4;
console.log(minimumCoins(N, X));
|
Time Complexity: O(N * 2N)
Auxiliary Space: O(1)
Efficient Approach: The problem can be solved efficiently using BFS based on the below idea:
- Build a graph out of the transitions. If we can go from T1 to some T2 using either one of the two operations, we can add an edge with weight = 1 from T1 to T2.
- Once the graph has been built, the minimum number of operations from 1 to N, would be the shortest distance from 1 to N in the graph.
However, since the number can be increased using the first operation, we need an upper bound to know when to stop building the graph.
- Suppose, an integer T consists of D digits. Using the second operation does not change the number of digits, and using the first operation either increases or keeps D the same.
- So now we know that the number of digits is non-decreasing. Hence, we don’t need to use any number with more digits than N, we can use 10*N as the upper limit.
Follow the below steps to solve this problem:
- Declare a distance array dis[10*N] to find the distance or minimum cost to convert 1 to N.
- Assign all the dis[i] to INF (Large Value)
- Start a BFS from node 1. In the BFS:
- If node = N, means we have reached the target. So break that call.
- If node*X < 10*N, push node*X into the queue for further usage in the BFS call.
- If node is not divisible by 10 and node>10 and right_shuffle(node)<10*N
- Push right_shuffle(node) into queue
- If reaching N (i.e. dis[N] = inf)is impossible return -1.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
int right_shuffle( int t)
{
auto str = to_string(t);
rotate(str.begin(), str.begin() +
str.size() - 1, str.end());
return stoi(str);
}
int minimumCoins( int n, int x)
{
const int INF = 1e9;
vector< int > dis(10 * n, INF);
vector< bool > vis(10 * n, 0);
dis[1] = 0, vis[1] = 1;
queue< int > q;
q.push(1);
while (!q.empty()) {
int curr = q.front();
q.pop();
if (curr == n)
break ;
if (1LL * curr * x < 10 * n
&& !vis[curr * x]) {
vis[curr * x] = 1;
q.push(curr * x);
dis[curr * x] = dis[curr] + 1;
}
if (curr <= 10 || curr % 10 == 0)
continue ;
int rt = right_shuffle(curr);
if (rt < 10 * n && !vis[rt]) {
vis[rt] = 1;
q.push(rt);
dis[rt] = dis[curr] + 1;
}
}
if (dis[n] == INF)
return -1;
else
return dis[n];
}
int main()
{
int N = 61, X = 4;
cout << minimumCoins(N, X);
return 0;
}
|
Java
import java.util.*;
class GFG{
static int right_shuffle( int t)
{
String str = String.valueOf(t);
str = rotate(str);
return Integer.parseInt(str);
}
static String rotate(String input) {
char [] a = input.toCharArray();
int l, r = a.length - 1 ;
for (l = 0 ; l < r; l++, r--) {
char temp = a[l];
a[l] = a[r];
a[r] = temp;
}
return String.valueOf(a);
}
static int minimumCoins( int n, int x)
{
int INF = ( int ) 1e9;
int dis[] = new int [ 10 *n];
int vis[] = new int [ 10 *n];
Arrays.fill(dis, 0 );
Arrays.fill(vis, 0 );
dis[ 1 ] = 0 ; vis[ 1 ] = 1 ;
Queue<Integer> q = new LinkedList<>();
q.add( 1 );
while (!q.isEmpty()) {
int curr = q.peek();
q.remove();
if (curr == n)
break ;
if ( 1 * curr * x < 10 * n
&& vis[curr * x]== 0 ) {
vis[curr * x] = 1 ;
q.add(curr * x);
dis[curr * x] = dis[curr] + 1 ;
}
if (curr <= 10 || curr % 10 == 0 )
continue ;
int rt = right_shuffle(curr);
if (rt < 10 * n && vis[rt]== 0 ) {
vis[rt] = 1 ;
q.add(rt);
dis[rt] = dis[curr] + 1 ;
}
}
if (dis[n] == INF)
return - 1 ;
else
return dis[n];
}
public static void main(String[] args)
{
int N = 61 , X = 4 ;
System.out.print(minimumCoins(N, X));
}
}
|
Python3
def right_shuffle(t):
str_ = str (t)
str_ = str_[ - 1 ] + str_[: len (str_) - 1 ]
return int (str_)
def minimumCoins(n, x):
INF = 1000000000
dis = [INF for _ in range ( 10 * n)]
vis = [ 0 for _ in range ( 10 * n)]
dis[ 1 ] = 0
vis[ 1 ] = 1
q = []
q.append( 1 )
while ( len (q) ! = 0 ):
curr = q.pop( 0 )
if (curr = = n):
break
if (curr * x < 10 * n and (vis[curr * x] = = 0 )):
vis[curr * x] = 1
q.append(curr * x)
dis[curr * x] = dis[curr] + 1
if ((curr < = 10 ) or (curr % 10 = = 0 )):
continue
rt = right_shuffle(curr)
if ((rt < 10 * n) and (vis[rt] = = 0 )):
vis[rt] = 1
q.append(rt)
dis[rt] = dis[curr] + 1
if (dis[n] = = INF):
return - 1
else :
return dis[n]
N = 61
X = 4
print (minimumCoins(N, X))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
static int right_shuffle( int t)
{
string str = Convert.ToString(t);
str = str[str.Length - 1]
+ str.Substring(0, str.Length - 1);
return Convert.ToInt32(str);
}
static int minimumCoins( int n, int x)
{
int INF = 1000000000;
List< int > dis = new List< int >();
for ( int i = 0; i < 10 * n; i++)
dis.Add(INF);
List< int > vis = new List< int >();
for ( int i = 0; i < 10 * n; i++)
vis.Add(0);
dis[1] = 0;
vis[1] = 1;
List< int > q = new List< int >();
q.Add(1);
while (q.Count != 0) {
int curr = q[0];
q.RemoveAt(0);
if (curr == n)
break ;
if (curr * x < 10 * n && (vis[curr * x] == 0)) {
vis[curr * x] = 1;
q.Add(curr * x);
dis[curr * x] = dis[curr] + 1;
}
if ((curr <= 10) || (curr % 10 == 0))
continue ;
int rt = right_shuffle(curr);
if ((rt < 10 * n) && (vis[rt] == 0)) {
vis[rt] = 1;
q.Add(rt);
dis[rt] = dis[curr] + 1;
}
}
if (dis[n] == INF)
return -1;
else
return dis[n];
}
public static void Main( string [] args)
{
int N = 61;
int X = 4;
Console.Write(minimumCoins(N, X));
}
}
|
Javascript
function right_shuffle(t)
{
let str = t.toString();
str = (str.charAt(str.length - 1) + str.slice(0, -1));
return parseInt(str);
}
function minimumCoins(n, x)
{
let INF = 1e9;
let dis = new Array(10 * n).fill(INF);
let vis = new Array(10 * n).fill(0);
dis[1] = 0;
vis[1] = 1;
let q = [];
q.push(1);
while (q.length != 0) {
let curr = q.shift();
if (curr == n)
break ;
if (curr * x < 10 * n
&& (vis[curr * x] == 0)) {
vis[curr * x] = 1;
q.push(curr * x);
dis[curr * x] = dis[curr] + 1;
}
if ((curr <= 10) || (curr % 10 == 0))
continue ;
let rt = right_shuffle(curr);
if ((rt < 10 * n) && (vis[rt] == 0)) {
vis[rt] = 1;
q.push(rt);
dis[rt] = dis[curr] + 1;
}
}
if (dis[n] == INF)
return -1;
else
return dis[n];
}
let N = 61;
let X = 4;
console.log(minimumCoins(N, X));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
28 Jul, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...