Minimum step to reach one
Last Updated :
14 Jul, 2022
Given a positive number N, we need to reach to 1 in minimum number of steps where a step is defined as converting N to (N-1) or converting N to its one of the bigger divisor.
Formally, if we are at N, then in 1 step we can reach to (N – 1) or if N = u*v then we can reach to max(u, v) where u > 1 and v > 1.
Examples:
Input : N = 17
Output : 4
We can reach to 1 in 4 steps as shown below,
17 -> 16(from 17 - 1) -> 4(from 4 * 4) ->
2(from 2 * 2) -> 1(from 2 - 1)
Input : N = 50
Output : 5
We can reach to 1 in 5 steps as shown below,
50 -> 10(from 5 * 10) -> 5(from 2 * 5) ->
4(from 5 - 1) -> 2(from 2 *2) -> 1(from 2 - 1)
We can solve this problem using breadth first search because it works level by level so we will reach to 1 in minimum number of steps where next level for N contains (N – 1) and bigger proper factors of N.
Complete BFS procedure will be as follows, First we will push N with steps 0 into the data queue then at each level we will push their next level elements with 1 step more than its previous level elements. In this way when 1 will be popped out from queue, it will contain minimum number of steps with it, which will be our final result.
In below code a queue of a structure of ‘data’ type is used which stores value and steps from N in it, another set of integer type is used to save ourselves from pushing the same element more than once which can lead to an infinite loop. So at each step, we push the value into set after pushing that into the queue so that the value won’t be visited more than once.
Please see below code for better understanding,
C++
#include <bits/stdc++.h>
using namespace std;
struct data
{
int val;
int steps;
data( int val, int steps) : val(val), steps(steps)
{}
};
int minStepToReachOne( int N)
{
queue<data> q;
q.push(data(N, 0));
set< int > st;
while (!q.empty())
{
data t = q.front(); q.pop();
if (t.val == 1)
return t.steps;
if (st.find(t.val - 1) == st.end())
{
q.push(data(t.val - 1, t.steps + 1));
st.insert(t.val - 1);
}
for ( int i = 2; i*i <= t.val; i++)
{
if (t.val % i == 0 && st.find(t.val / i) == st.end())
{
q.push(data(t.val / i, t.steps + 1));
st.insert(t.val / i);
}
}
}
}
int main()
{
int N = 17;
cout << minStepToReachOne(N) << endl;
}
|
Java
import java.util.*;
class GFG
{
static class data
{
int val;
int steps;
public data( int val, int steps)
{
this .val = val;
this .steps = steps;
}
};
static int minStepToReachOne( int N)
{
Queue<data> q = new LinkedList<>();
q.add( new data(N, 0 ));
HashSet<Integer> st = new HashSet<Integer>();
while (!q.isEmpty())
{
data t = q.peek(); q.remove();
if (t.val == 1 )
return t.steps;
if (!st.contains(t.val - 1 ))
{
q.add( new data(t.val - 1 , t.steps + 1 ));
st.add(t.val - 1 );
}
for ( int i = 2 ; i*i <= t.val; i++)
{
if (t.val % i == 0 && !st.contains(t.val / i) )
{
q.add( new data(t.val / i, t.steps + 1 ));
st.add(t.val / i);
}
}
}
return - 1 ;
}
public static void main(String[] args)
{
int N = 17 ;
System.out.print(minStepToReachOne(N) + "\n" );
}
}
|
Python3
class data:
def __init__( self , val, steps):
self .val = val
self .steps = steps
def minStepToReachOne(N):
q = []
q.append(data(N, 0 ))
st = set ()
while ( len (q)):
t = q.pop( 0 )
if (t.val = = 1 ):
return t.steps
if not (t.val - 1 ) in st:
q.append(data(t.val - 1 , t.steps + 1 ))
st.add(t.val - 1 )
for i in range ( 2 , int ((t.val) * * 0.5 ) + 1 ):
if (t.val % i = = 0 and (t.val / i) not in st):
q.append(data(t.val / i, t.steps + 1 ))
st.add(t.val / i)
return - 1
N = 17
print (minStepToReachOne(N))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
class data
{
public int val;
public int steps;
public data( int val, int steps)
{
this .val = val;
this .steps = steps;
}
};
static int minStepToReachOne( int N)
{
Queue<data> q = new Queue<data>();
q.Enqueue( new data(N, 0));
HashSet< int > st = new HashSet< int >();
while (q.Count != 0)
{
data t = q.Peek(); q.Dequeue();
if (t.val == 1)
return t.steps;
if (!st.Contains(t.val - 1))
{
q.Enqueue( new data(t.val - 1, t.steps + 1));
st.Add(t.val - 1);
}
for ( int i = 2; i*i <= t.val; i++)
{
if (t.val % i == 0 && !st.Contains(t.val / i) )
{
q.Enqueue( new data(t.val / i, t.steps + 1));
st.Add(t.val / i);
}
}
}
return -1;
}
public static void Main(String[] args)
{
int N = 17;
Console.Write(minStepToReachOne(N) + "\n" );
}
}
|
Javascript
<script>
class data
{
constructor(val, steps)
{
this .val = val;
this .steps = steps;
}
}
function minStepToReachOne(N)
{
let q = [];
q.push( new data(N, 0));
let st = new Set();
while (q.length != 0)
{
let t = q.shift();
if (t.val == 1)
return t.steps;
if (!st.has(t.val - 1))
{
q.push( new data(t.val - 1,
t.steps + 1));
st.add(t.val - 1);
}
for (let i = 2; i*i <= t.val; i++)
{
if (t.val % i == 0 && !st.has(t.val / i))
{
q.push( new data(t.val / i,
t.steps + 1));
st.add(t.val / i);
}
}
}
return -1;
}
let N = 17;
document.write(minStepToReachOne(N) + "<br>" );
</script>
|
Output:
4
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...