Open In App

Min steps to convert N-digit prime number into another by replacing a digit in each step

Given two N-digit prime numbers A and B, the task is to find the minimum number of steps taken to convert A to B. Condition for the conversion is that only 1 digit of the current prime number can be modified such that the new number formed is also a prime number. If no such conversion is possible, print -1. 

Note: The range of N is [1, 5]. 

Examples: 

Input: N = 4, A = 1033, B = 8179 
Output:
Explanation: The steps of conversion are 1033 -> 1733 -> 3733 -> 3739 -> 3779 -> 8779 -> 8179. While changing numbers from 1033->1733, they differ by only one digit and the same happens for subsequent steps.

Input: N = 4, A = 1373, B = 8179 
Output: 7

Input: N = 2, A = 11, B = 37 
Output:
Explanation: The steps of conversion are 11 -> 17 -> 37 

Approach: Using Breadth First Search Algorithm 

  1. Find all N digit prime numbers and make a graph with these numbers.
  2. Consider each prime number as a node of a graph and create an edge from one node to another if they differ by a single digit.
  3. Apply BFS traversal and find out the number of edges between A and B.
  4. If no path exists, print -1.
  5. Else print the no. of edges, which is the required solution.

Below is the implementation of the above approach. 




// C++ program for the above problem
 
#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define mod 1000000007
#define pb push_back
#define mod 1000000007
#define vi vector<int>
 
// adjacency list for numbers
// till 100001
vi lis[100001];
vi primes;
 
// visited array
int vis[100001];
 
// to store distance of every
// vertex from A
int dis[100001];
 
// function to check if number
// is a prime
bool isPrime(int n)
{
    for (int i = 2;
         i * i <= n; i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}
 
// function to check if numbers
// differ by only a single-digit
bool valid(int a, int b)
{
    int c = 0;
    while (a) {
 
        // check the last digit of
        // both numbers and increase
        // count if different
        if ((a % 10) != (b % 10)) {
            c++;
        }
        a = a / 10;
        b = b / 10;
    }
    if (c == 1) {
        return true;
    }
    else {
        return false;
    }
}
 
void makePrimes(int N)
{
    int i, j;
    int L = pow(10, N - 1);
    int R = pow(10, N) - 1;
    // generate all N digit primes
    for (int i = L; i <= R; i++) {
        if (isPrime(i)) {
            primes.pb(i);
        }
    }
    for (i = 0;
         i < primes.size(); i++) {
 
        // for every prime number i
        // check if an edge
        // can be made.
        for (j = i + 1;
             j < primes.size(); j++) {
            int a = primes[i];
            int b = primes[j];
 
            // for every prime number
            // i check if an edge can
            // be made from i to j.
            if (valid(a, b)) {
 
                // if edge is possible then
                // insert in the adjacency
                // list
                lis[a].pb(b);
                lis[b].pb(a);
            }
        }
    }
}
 
// function to count distance
void bfs(int src)
{
    queue<int> q;
    q.push(src);
    vis[src] = 1;
    dis[src] = 0;
    while (!q.empty()) {
        int curr = q.front();
        q.pop();
        for (int x : lis[curr]) {
 
            // if unvisited push onto queue
            // and mark visited as 1 and
            // add the distance of curr+1.
            if (vis[x] == 0) {
                vis[x] = 1;
                q.push(x);
                dis[x] = dis[curr] + 1;
            }
        }
    }
}
 
// Driver code
int main()
{
    int N = 4;
    makePrimes(N);
    int A = 1033, B = 8179;
 
    // Call bfs traversal
    // with root as node A
    bfs(A);
 
    if (dis[B] == -1)
       
        // Indicates not possible
        cout << "-1" << endl;
    else
        cout << dis[B] << endl;
 
    return 0;
}




// Java program for the above problem
import java.util.*;
public class GFG
{
 
  // Adjacency list for numbers
  // till 100001
  static Vector<Vector<Integer>> lis = new Vector<Vector<Integer>>();    
  static Vector<Integer> primes = new Vector<Integer>();
 
  // Visited array
  static int[] vis = new int[100001];
 
  // To store distance of every
  // vertex from A
  static int[] dis = new int[100001];
 
  // Function to check if number
  // is a prime
  static boolean isPrime(int n)
  {
    int i = 2;
    while (i * i <= n)
    {
      if (n % i == 0)
        return false;
      i += 1;
    }
    return true;
  }
 
  // Function to check if numbers
  // differ by only a single-digit
  static boolean valid(int a, int b)
  {
    int c = 0;       
    while(a > 0)
    {
 
      // Check the last digit of
      // both numbers and increase
      // count if different
      if ((a % 10) != (b % 10))
        c += 1;            
      a = a / 10;
      b = b / 10;
    }    
    if (c == 1)
      return true;
    else
      return false;
  }
 
  static void makePrimes(int N)
  {
 
    // Generate all N digit primes
    int L = (int)Math.pow(10, N - 1);
    int R = (int)Math.pow(10, N) - 1;
 
    for(int i = L; i < R + 1; i++)
    {
      if (isPrime(i))
        primes.add(i);
    }
 
    for(int i = 0; i < primes.size(); i++)
    {
 
      // For every prime number i
      // check if an edge
      // can be made.
      for(int j = i + 1; j < primes.size(); j++)
      {
        int a = primes.get(i);
        int b = primes.get(j);
 
        // For every prime number
        // i check if an edge can
        // be made from i to j.
        if (valid(a, b))
        {
 
          // If edge is possible then
          // insert in the adjacency
          // list
          lis.get(a).add(b);
          lis.get(b).add(a);
        }
      }
    }
  }
 
  // Function to count distance
  static void bfs(int src)
  {
    Vector<Integer> q = new Vector<Integer>();
    q.add(src);
    vis[src] = 1;
    dis[src] = 0;
    while (q.size() != 0)
    {
      int curr = q.get(0);
      q.remove(0);
      for(int x : lis.get(curr))
      {
        // If unvisited push onto queue
        // and mark visited as 1 and
        // add the distance of curr+1.
        if (vis[x] == 0)
        {
          vis[x] = 1;
          q.add(x);
          dis[x] = dis[curr] + 1;
        }
      }
    }
  }
 
  // Driver code
  public static void main(String[] args)
  {
    for(int i = 0; i < 100001; i++)
    {
      lis.add(new Vector<Integer>());
    }
    int N = 4;
    makePrimes(N);
    int A = 1033;
    int B = 8179;
 
    // Call bfs traversal
    // with root as node A
    bfs(A);
 
    if (dis[B] == -1)
    {
      // Indicates not possible
      System.out.print(-1);
    }
    else
    {
      System.out.print(dis[B]);
    }
  }
}
 
// This code is contributed by divyesh072019




# Python3 program for the above problem
mod = 1000000007
 
# Adjacency list for numbers
# till 100001
lis = [[] for i in range(100001)]
primes = []
 
# Visited array
vis = [0 for i in range(100001)]
 
# To store distance of every
# vertex from A
dis = [0 for i in range(100001)]
 
# Function to check if number
# is a prime
def isPrime(n):
     
    i = 2
    while (i * i <= n):
        if (n % i == 0):
            return False
             
        i += 1
         
    return True
 
# Function to check if numbers
# differ by only a single-digit
def valid(a, b):
     
    c = 0
     
    while(a):
         
        # Check the last digit of
        # both numbers and increase
        # count if different
        if ((a % 10) != (b % 10)):
            c += 1
             
        a = int(a / 10)
        b = int(b / 10)
 
    if (c == 1):
        return True
    else:
        return False
 
def makePrimes(N):
     
    global primes
    global lis
    i = 0
    j = 0
     
    # Generate all N digit primes
    L = pow(10, N - 1)
    R = pow(10, N) - 1
 
    for i in range(L, R + 1):
        if (isPrime(i)):
            primes.append(i)
             
    for i in range(len(primes)):
         
        # For every prime number i
        # check if an edge
        # can be made.
        for j in range(i + 1, len(primes)):
            a = primes[i]
            b = primes[j]
 
            # For every prime number
            # i check if an edge can
            # be made from i to j.
            if (valid(a, b)):
                 
                # If edge is possible then
                # insert in the adjacency
                # list
                lis[a].append(b)
                lis[b].append(a)
 
# Function to count distance
def bfs(src):
     
    global vis
    global dis
    q = []
    q.append(src)
    vis[src] = 1
    dis[src] = 0
 
    while (len(q) != 0):
        curr = q[0]
        q.pop(0)
         
        for x in lis[curr]:
             
            # If unvisited push onto queue
            # and mark visited as 1 and
            # add the distance of curr+1.
            if (vis[x] == 0):
                vis[x] = 1
                q.append(x)
                dis[x] = dis[curr] + 1
 
# Driver code
N = 4
makePrimes(N)
A = 1033
B = 8179
 
# Call bfs traversal
# with root as node A
bfs(A)
 
if (dis[B] == -1):
     
    # Indicates not possible
    print(-1)
else:
    print(dis[B])
 
# This code is contributed by avanitrachhadiya2155




// C# program for the above problem
using System;
using System.Collections.Generic;
class GFG {
  
    // Adjacency list for numbers
    // till 100001
    static List<List<int>> lis = new List<List<int>>();
     
    static List<int> primes = new List<int>();
      
    // Visited array
    static int[] vis = new int[100001];
      
    // To store distance of every
    // vertex from A
    static int[] dis = new int[100001];
     
    // Function to check if number
    // is a prime
    static bool isPrime(int n)
    {
        int i = 2;
        while (i * i <= n)
        {
            if (n % i == 0)
                return false;
            i += 1;
        }
        return true;
    }
     
    // Function to check if numbers
    // differ by only a single-digit
    static bool valid(int a, int b)
    {
        int c = 0;
          
        while(a > 0)
        {
            // Check the last digit of
            // both numbers and increase
            // count if different
            if ((a % 10) != (b % 10))
                c += 1;
                  
            a = a / 10;
            b = b / 10;
        }
      
        if (c == 1)
            return true;
        else
            return false;
    }
     
    static void makePrimes(int N)
    {
       
        // Generate all N digit primes
        int L = (int)Math.Pow(10, N - 1);
        int R = (int)Math.Pow(10, N) - 1;
      
        for(int i = L; i < R + 1; i++)
        {
            if (isPrime(i))
                primes.Add(i);
        }
                  
        for(int i = 0; i < primes.Count; i++)
        {
           
            // For every prime number i
            // check if an edge
            // can be made.
            for(int j = i + 1; j < primes.Count; j++)
            {
                int a = primes[i];
                int b = primes[j];
      
                // For every prime number
                // i check if an edge can
                // be made from i to j.
                if (valid(a, b))
                {
                    // If edge is possible then
                    // insert in the adjacency
                    // list
                    lis[a].Add(b);
                    lis[b].Add(a);
                }
            }
        }
    }
     
    // Function to count distance
    static void bfs(int src)
    {
        List<int> q = new List<int>();
        q.Add(src);
        vis[src] = 1;
        dis[src] = 0;
      
        while (q.Count != 0)
        {
            int curr = q[0];
            q.RemoveAt(0);
              
            foreach(int x in lis[curr])
            {
                // If unvisited push onto queue
                // and mark visited as 1 and
                // add the distance of curr+1.
                if (vis[x] == 0)
                {
                    vis[x] = 1;
                    q.Add(x);
                    dis[x] = dis[curr] + 1;
                }
            }
        }
    }
 
  // Driver code
  static void Main()
  {
    for(int i = 0; i < 100001; i++)
    {
        lis.Add(new List<int>());
    }
    int N = 4;
    makePrimes(N);
    int A = 1033;
    int B = 8179;
      
    // Call bfs traversal
    // with root as node A
    bfs(A);
      
    if (dis[B] == -1)
    {
        // Indicates not possible
        Console.Write(-1);
    }
    else
    {
        Console.Write(dis[B]);
    }
  }
}




// JS program for the above problem
let mod = 1000000007
 
// adjacency list for numbers
// till 100001
let lis = new Array(100001);
for (var i = 0; i < 100001; i++)
    lis[i] = new Array();
     
let primes = [];
 
// visited array
let vis = new Array(100001).fill(0);
 
// to store distance of every
// vertex from A
let dis = new Array(100001).fill(0);
 
// function to check if number
// is a prime
function isPrime(n)
{
    for (let i = 2;
         i * i <= n; i++) {
        if (n % i == 0)
            return false;
    }
    return true;
}
 
// function to check if numbers
// differ by only a single-digit
function valid(a, b)
{
    let c = 0;
    while (a > 0) {
 
        // check the last digit of
        // both numbers and increase
        // count if different
        if ((a % 10) != (b % 10)) {
            c++;
        }
        a = Math.floor(a / 10);
        b = Math.floor(b / 10);
    }
    if (c == 1) {
        return true;
    }
    else {
        return false;
    }
}
 
function makePrimes( N)
{
    let i, j;
    let L = 10 ** (N - 1);
    let R = (10 ** N) - 1;
     
    // generate all N digit primes
    for (i = L; i <= R; i++) {
        if (isPrime(i)) {
            primes.push(i);
        }
    }
     
    for (i = 0; i < primes.length; i++) {
 
        // for every prime number i
        // check if an edge
        // can be made.
        for (j = i + 1; j < primes.length; j++) {
            let a = primes[i];
            let b = primes[j];
 
            // for every prime number
            // i check if an edge can
            // be made from i to j.
            if (valid(a, b)) {
                 
                //console.log(lis[a], lis[b])
                // if edge is possible then
                // insert in the adjacency
                // list
                let l1 = lis[a]
                let l2 = lis[b]
                l1.push(b)
                l2.push(a)
                lis[a] = l1
                lis[b] = l2;
            }
        }
    }
}
 
// function to count distance
function bfs(src)
{
    let q = [];
    q.push(src);
    vis[src] = 1;
    dis[src] = 0;
    while ( q.length > 0) {
        let curr = q[0];
        q.shift();
        for (let x of lis[curr]) {
 
            // if unvisited push onto queue
            // and mark visited as 1 and
            // add the distance of curr+1.
            if (vis[x] == 0) {
                vis[x] = 1;
                q.push(x);
                dis[x] = dis[curr] + 1;
            }
        }
    }
}
 
// Driver code
let N = 4;
makePrimes(N);
let A = 1033, B = 8179;
 
// Call bfs traversal
// with root as node A
bfs(A);
 
if (dis[B] == -1)
    // Indicates not possible
    console.log(-1)
else
    console.log(dis[B]);
 
// This code is contributed by phasing17.

Output: 
6

 

Time Complexity: O(102N
Auxiliary Space Complexity: O(105)
 


Article Tags :