Given two four digit prime numbers, suppose 1033 and 8179, we need to find the shortest path from 1033 to 8179 by altering only single digit at a time such that every number that we get after changing a digit is prime. For example a solution is 1033, 1733, 3733, 3739, 3779, 8779, 8179
Examples:
Input : 1033 8179
Output :6
Explanation : One possible transformation sequence is 1033 -> 1733 -> 3733 -> 3739 -> 3779 -> 8779 -> 8179. In each step, exactly one digit is changed, and all intermediate numbers are valid four-digit prime numbers. A total of 6 steps are required to transform,Input : 1373 8017
Output : 7Input : 1033 1033
Output : 0
Table of Content
[Naive Approach] Using Graph Construction + BFS – O(p² + p√n) Time and O(p²) Space
The idea is to treat every 4-digit prime number as a node in a graph. Two prime numbers are connected if they differ by exactly one digit. After constructing the graph, we use BFS to find the shortest path from the starting prime to the target prime. Since BFS always finds the minimum number of transformations in an unweighted graph, it gives the required answer.
- Generate all 4-digit prime numbers and store them as graph nodes
- Compare every pair of primes and connect those differing by one digit
- Find indices of source and destination prime numbers
- Perform BFS traversal to compute the shortest transformation path
#include <bits/stdc++.h>
using namespace std;
// Function to check if a number is prime
bool isPrime(int n)
{
if (n < 2)
return false;
for (int i = 2; i * i <= n; i++)
{
if (n % i == 0)
return false;
}
return true;
}
// Returns true if num1 and num2 differ
// by single digit.
bool compare(int num1, int num2)
{
// To compare the digits
string s1 = to_string(num1);
string s2 = to_string(num2);
int c = 0;
if (s1[0] != s2[0])
c++;
if (s1[1] != s2[1])
c++;
if (s1[2] != s2[2])
c++;
if (s1[3] != s2[3])
c++;
// If the numbers differ only by a single
// digit return true else false
return (c == 1);
}
// Function to find minimum steps
int minStep(int num1, int num2)
{
// Store all 4 digit prime numbers
vector<int> primes;
// Check every number from 1000 to 9999
for (int i = 1000; i <= 9999; i++)
{
if (isPrime(i))
primes.push_back(i);
}
int n = primes.size();
// Create graph
vector<vector<int>> adj(n);
// Compare every pair of primes
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
// Connect if they differ by one digit
if (compare(primes[i], primes[j]))
{
adj[i].push_back(j);
adj[j].push_back(i);
}
}
}
int start, end;
// Find index of num1
for (int i = 0; i < n; i++)
{
if (primes[i] == num1)
start = i;
}
// Find index of num2
for (int i = 0; i < n; i++)
{
if (primes[i] == num2)
end = i;
}
// BFS traversal
vector<int> visited(n, 0);
queue<int> q;
visited[start] = 1;
q.push(start);
while (!q.empty())
{
int node = q.front();
q.pop();
for (auto next : adj[node])
{
if (!visited[next])
{
visited[next] = visited[node] + 1;
q.push(next);
}
if (next == end)
return visited[next] - 1;
}
}
return 0;
}
// Driver code
int main()
{
int num1 = 1033;
int num2 = 8179;
cout << minStep(num1, num2) << endl;
return 0;
}
// Java program to find minimum steps to convert one prime to another
import java.util.*;
class GfG {
// Function to check if a number is prime
static boolean isPrime(int n) {
if (n < 2)
return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return false;
}
return true;
}
// Returns true if num1 and num2 differ by single digit
static boolean compare(int num1, int num2) {
String s1 = String.valueOf(num1);
String s2 = String.valueOf(num2);
int c = 0;
for (int i = 0; i < 4; i++) {
if (s1.charAt(i) != s2.charAt(i))
c++;
}
return (c == 1);
}
// Function to find minimum steps
static int minStep(int num1, int num2) {
// Store all 4 digit prime numbers
List<Integer> primes = new ArrayList<>();
// Check every number from 1000 to 9999
for (int i = 1000; i <= 9999; i++) {
if (isPrime(i))
primes.add(i);
}
int n = primes.size();
// Create graph
List<List<Integer>> adj = new ArrayList<>();
for (int i = 0; i < n; i++) {
adj.add(new ArrayList<>());
}
// Compare every pair of primes
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Connect if they differ by one digit
if (compare(primes.get(i), primes.get(j))) {
adj.get(i).add(j);
adj.get(j).add(i);
}
}
}
int start = -1, end = -1;
// Find index of num1
for (int i = 0; i < n; i++) {
if (primes.get(i) == num1)
start = i;
}
// Find index of num2
for (int i = 0; i < n; i++) {
if (primes.get(i) == num2)
end = i;
}
// BFS traversal
int[] visited = new int[n];
Queue<Integer> q = new LinkedList<>();
visited[start] = 1;
q.add(start);
while (!q.isEmpty()) {
int node = q.poll();
for (int next : adj.get(node)) {
if (visited[next] == 0) {
visited[next] = visited[node] + 1;
q.add(next);
}
if (next == end)
return visited[next] - 1;
}
}
return 0;
}
// Driver code
public static void main(String[] args) {
int num1 = 1033;
int num2 = 8179;
System.out.println(minStep(num1, num2));
}
}
# Python program to find minimum steps to convert one prime to another
from collections import deque
# Function to check if a number is prime
def isPrime(n):
if n < 2:
return False
i = 2
while i * i <= n:
if n % i == 0:
return False
i += 1
return True
# Returns true if num1 and num2 differ by single digit
def compare(num1, num2):
s1 = str(num1)
s2 = str(num2)
c = 0
for i in range(4):
if s1[i] != s2[i]:
c += 1
return c == 1
# Function to find minimum steps
def minStep(num1, num2):
# Store all 4 digit prime numbers
primes = []
# Check every number from 1000 to 9999
for i in range(1000, 10000):
if isPrime(i):
primes.append(i)
n = len(primes)
# Create graph
adj = [[] for _ in range(n)]
# Compare every pair of primes
for i in range(n):
for j in range(i + 1, n):
# Connect if they differ by one digit
if compare(primes[i], primes[j]):
adj[i].append(j)
adj[j].append(i)
# Find index of num1 and num2
start = primes.index(num1)
end = primes.index(num2)
# BFS traversal
visited = [0] * n
q = deque()
visited[start] = 1
q.append(start)
while q:
node = q.popleft()
for next_node in adj[node]:
if not visited[next_node]:
visited[next_node] = visited[node] + 1
q.append(next_node)
if next_node == end:
return visited[next_node] - 1
return 0
# Driver code
if __name__ == "__main__":
num1 = 1033
num2 = 8179
print(minStep(num1, num2))
// C# program to find minimum steps to convert one prime to another
using System;
using System.Collections.Generic;
class GfG {
// Function to check if a number is prime
static bool isPrime(int n) {
if (n < 2)
return false;
for (int i = 2; i * i <= n; i++) {
if (n % i == 0)
return false;
}
return true;
}
// Returns true if num1 and num2 differ by single digit
static bool compare(int num1, int num2) {
string s1 = num1.ToString();
string s2 = num2.ToString();
int c = 0;
for (int i = 0; i < 4; i++) {
if (s1[i] != s2[i])
c++;
}
return (c == 1);
}
// Function to find minimum steps
static int minStep(int num1, int num2) {
// Store all 4 digit prime numbers
List<int> primes = new List<int>();
// Check every number from 1000 to 9999
for (int i = 1000; i <= 9999; i++) {
if (isPrime(i))
primes.Add(i);
}
int n = primes.Count;
// Create graph
List<List<int>> adj = new List<List<int>>();
for (int i = 0; i < n; i++) {
adj.Add(new List<int>());
}
// Compare every pair of primes
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Connect if they differ by one digit
if (compare(primes[i], primes[j])) {
adj[i].Add(j);
adj[j].Add(i);
}
}
}
int start = -1, end = -1;
// Find index of num1
for (int i = 0; i < n; i++) {
if (primes[i] == num1)
start = i;
}
// Find index of num2
for (int i = 0; i < n; i++) {
if (primes[i] == num2)
end = i;
}
// BFS traversal
int[] visited = new int[n];
Queue<int> q = new Queue<int>();
visited[start] = 1;
q.Enqueue(start);
while (q.Count > 0) {
int node = q.Dequeue();
foreach (int next in adj[node]) {
if (visited[next] == 0) {
visited[next] = visited[node] + 1;
q.Enqueue(next);
}
if (next == end)
return visited[next] - 1;
}
}
return 0;
}
// Driver code
static void Main(string[] args) {
int num1 = 1033;
int num2 = 8179;
Console.WriteLine(minStep(num1, num2));
}
}
// JavaScript program to find minimum steps to convert one prime to another
// Function to check if a number is prime
function isPrime(n) {
if (n < 2) return false;
for (let i = 2; i * i <= n; i++) {
if (n % i === 0) return false;
}
return true;
}
// Returns true if num1 and num2 differ by single digit
function compare(num1, num2) {
let s1 = num1.toString();
let s2 = num2.toString();
let c = 0;
for (let i = 0; i < 4; i++) {
if (s1[i] !== s2[i]) c++;
}
return c === 1;
}
// Function to find minimum steps
function minStep(num1, num2) {
// Store all 4 digit prime numbers
let primes = [];
// Check every number from 1000 to 9999
for (let i = 1000; i <= 9999; i++) {
if (isPrime(i)) primes.push(i);
}
let n = primes.length;
// Create graph
let adj = Array.from({ length: n }, () => []);
// Compare every pair of primes
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// Connect if they differ by one digit
if (compare(primes[i], primes[j])) {
adj[i].push(j);
adj[j].push(i);
}
}
}
let start = -1, end = -1;
// Find index of num1
for (let i = 0; i < n; i++) {
if (primes[i] === num1) start = i;
}
// Find index of num2
for (let i = 0; i < n; i++) {
if (primes[i] === num2) end = i;
}
// BFS traversal
let visited = new Array(n).fill(0);
let queue = [];
visited[start] = 1;
queue.push(start);
while (queue.length > 0) {
let node = queue.shift();
for (let next of adj[node]) {
if (!visited[next]) {
visited[next] = visited[node] + 1;
queue.push(next);
}
if (next === end) return visited[next] - 1;
}
}
return 0;
}
// Driver code
const num1 = 1033;
const num2 = 8179;
console.log(minStep(num1, num2));
[Efficient Approach] Using BFS on Prime Transformations – O(10⁴ × 4 × 10) Time and O(10⁴) Space
The idea is to treat every 4-digit prime number as a node in a graph. Two prime numbers are connected if they differ by exactly one digit. Starting from
num1, Breadth First Search (BFS) is used to explore all valid prime transformations level by level. Since BFS always reaches a node using the minimum number of steps first, the first timenum2is reached gives the shortest transformation sequence.To efficiently verify whether a number is prime, the Sieve of Eratosthenes is used to precompute all 4-digit prime numbers.
- Generate all prime numbers up to
9999using Sieve of Eratosthenes - Start BFS from
num1 - For every current number: Change each digit from
0to9, sSkip invalid transformations like leading zero and same digit replacement - If the generated number is a valid unvisited prime, Push it into the queue and store distance as current steps + 1
- Return the distance when
num2is reached. If unreachable, return-1
#include <bits/stdc++.h>
using namespace std;
int minStep(int num1, int num2) {
// If source and destination are the same, 0 steps needed
if (num1 == num2)
return 0;
// Sieve of Eratosthenes to precompute 4-digit primes
vector<bool> isPrime(10000, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < 10000; i++) {
if (isPrime[i]) {
for (int j = i * i; j < 10000; j += i) {
isPrime[j] = false;
}
}
}
// BFS to find the shortest path
vector<int> dist(10000, -1);
queue<int> q;
q.push(num1);
dist[num1] = 0;
while (!q.empty()) {
int curr = q.front();
q.pop();
string s = to_string(curr);
// Try changing each of the 4 digits
for (int i = 0; i < 4; i++) {
char originalChar = s[i];
// Try replacing the digit with '0' through '9'
for (char ch = '0'; ch <= '9'; ch++) {
// Skip if the digit is the same or if it creates a leading zero
if (ch == originalChar || (ch == '0' && i == 0)) {
continue;
}
s[i] = ch; // Modify in place
int nextNum = stoi(s);
// If it's a prime and hasn't been visited yet
if (isPrime[nextNum] && dist[nextNum] == -1) {
dist[nextNum] = dist[curr] + 1;
// Early exit if we reached the target
if (nextNum == num2) {
return dist[nextNum];
}
q.push(nextNum);
}
}
// Backtrack to the original string for the next position
s[i] = originalChar;
}
}
// If num2 is unreachable
return -1;
}
int main() {
int num1 = 1033, num2 = 8179;
cout << minStep(num1, num2) << endl;
return 0;
}
// Java program to find minimum steps to convert one prime to another
// Using Sieve of Eratosthenes and BFS
import java.util.*;
class GfG {
static int minStep(int num1, int num2) {
// If source and destination are the same, 0 steps needed
if (num1 == num2)
return 0;
// Sieve of Eratosthenes to precompute 4-digit primes
boolean[] isPrime = new boolean[10000];
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < 10000; i++) {
if (isPrime[i]) {
for (int j = i * i; j < 10000; j += i) {
isPrime[j] = false;
}
}
}
// BFS to find the shortest path
int[] dist = new int[10000];
Arrays.fill(dist, -1);
Queue<Integer> q = new LinkedList<>();
q.add(num1);
dist[num1] = 0;
while (!q.isEmpty()) {
int curr = q.poll();
String s = Integer.toString(curr);
// Try changing each of the 4 digits
for (int i = 0; i < 4; i++) {
char originalChar = s.charAt(i);
char[] chars = s.toCharArray();
// Try replacing the digit with '0' through '9'
for (char ch = '0'; ch <= '9'; ch++) {
// Skip if the digit is the same or if it creates a leading zero
if (ch == originalChar || (ch == '0' && i == 0)) {
continue;
}
chars[i] = ch;
int nextNum = Integer.parseInt(new String(chars));
// If it's a prime and hasn't been visited yet
if (isPrime[nextNum] && dist[nextNum] == -1) {
dist[nextNum] = dist[curr] + 1;
// Early exit if we reached the target
if (nextNum == num2) {
return dist[nextNum];
}
q.add(nextNum);
}
}
}
}
// If num2 is unreachable
return -1;
}
// Driver code
public static void main(String[] args) {
int num1 = 1033, num2 = 8179;
System.out.println(minStep(num1, num2));
}
}
# Python program to find minimum steps to convert one prime to another
# Using Sieve of Eratosthenes and BFS
from collections import deque
def minStep(num1, num2):
# If source and destination are the same, 0 steps needed
if num1 == num2:
return 0
# Sieve of Eratosthenes to precompute 4-digit primes
isPrime = [True] * 10000
isPrime[0] = isPrime[1] = False
for i in range(2, int(10000 ** 0.5) + 1):
if isPrime[i]:
for j in range(i * i, 10000, i):
isPrime[j] = False
# BFS to find the shortest path
dist = [-1] * 10000
q = deque()
q.append(num1)
dist[num1] = 0
while q:
curr = q.popleft()
s = str(curr)
# Try changing each of the 4 digits
for i in range(4):
original_char = s[i]
# Try replacing the digit with '0' through '9'
for ch in '0123456789':
# Skip if the digit is the same or if it creates a leading zero
if ch == original_char or (ch == '0' and i == 0):
continue
next_num = int(s[:i] + ch + s[i+1:])
# If it's a prime and hasn't been visited yet
if isPrime[next_num] and dist[next_num] == -1:
dist[next_num] = dist[curr] + 1
# Early exit if we reached the target
if next_num == num2:
return dist[next_num]
q.append(next_num)
# If num2 is unreachable
return -1
# Driver code
if __name__ == "__main__":
num1, num2 = 1033, 8179
print(minStep(num1, num2))
// C# program to find minimum steps to convert one prime to another
// Using Sieve of Eratosthenes and BFS
using System;
using System.Collections.Generic;
class GfG {
static int minStep(int num1, int num2) {
// If source and destination are the same, 0 steps needed
if (num1 == num2)
return 0;
// Sieve of Eratosthenes to precompute 4-digit primes
bool[] isPrime = new bool[10000];
for (int i = 0; i < 10000; i++)
isPrime[i] = true;
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i < 10000; i++) {
if (isPrime[i]) {
for (int j = i * i; j < 10000; j += i) {
isPrime[j] = false;
}
}
}
// BFS to find the shortest path
int[] dist = new int[10000];
for (int i = 0; i < 10000; i++)
dist[i] = -1;
Queue<int> q = new Queue<int>();
q.Enqueue(num1);
dist[num1] = 0;
while (q.Count > 0) {
int curr = q.Dequeue();
string s = curr.ToString();
// Try changing each of the 4 digits
for (int i = 0; i < 4; i++) {
char originalChar = s[i];
char[] chars = s.ToCharArray();
// Try replacing the digit with '0' through '9'
for (char ch = '0'; ch <= '9'; ch++) {
// Skip if the digit is the same or if it creates a leading zero
if (ch == originalChar || (ch == '0' && i == 0)) {
continue;
}
chars[i] = ch;
int nextNum = int.Parse(new string(chars));
// If it's a prime and hasn't been visited yet
if (isPrime[nextNum] && dist[nextNum] == -1) {
dist[nextNum] = dist[curr] + 1;
// Early exit if we reached the target
if (nextNum == num2) {
return dist[nextNum];
}
q.Enqueue(nextNum);
}
}
}
}
// If num2 is unreachable
return -1;
}
// Driver code
static void Main(string[] args) {
int num1 = 1033, num2 = 8179;
Console.WriteLine(minStep(num1, num2));
}
}
// JavaScript program to find minimum steps to convert one prime to another
// Using Sieve of Eratosthenes and BFS
function minStep(num1, num2) {
// If source and destination are the same, 0 steps needed
if (num1 === num2)
return 0;
// Sieve of Eratosthenes to precompute 4-digit primes
let isPrime = new Array(10000).fill(true);
isPrime[0] = isPrime[1] = false;
for (let i = 2; i * i < 10000; i++) {
if (isPrime[i]) {
for (let j = i * i; j < 10000; j += i) {
isPrime[j] = false;
}
}
}
// BFS to find the shortest path
let dist = new Array(10000).fill(-1);
let queue = [];
queue.push(num1);
dist[num1] = 0;
while (queue.length > 0) {
let curr = queue.shift();
let s = curr.toString();
// Try changing each of the 4 digits
for (let i = 0; i < 4; i++) {
let originalChar = s[i];
// Try replacing the digit with '0' through '9'
for (let ch = '0'; ch <= '9'; ch = String.fromCharCode(ch.charCodeAt(0) + 1)) {
// Skip if the digit is the same or if it creates a leading zero
if (ch === originalChar || (ch === '0' && i === 0)) {
continue;
}
let nextNum = parseInt(s.substring(0, i) + ch + s.substring(i + 1));
// If it's a prime and hasn't been visited yet
if (isPrime[nextNum] && dist[nextNum] === -1) {
dist[nextNum] = dist[curr] + 1;
// Early exit if we reached the target
if (nextNum === num2) {
return dist[nextNum];
}
queue.push(nextNum);
}
}
}
}
// If num2 is unreachable
return -1;
}
// Driver code
const num1 = 1033, num2 = 8179;
console.log(minStep(num1, num2));
Output :
6