Largest number not greater than N which can become prime after rearranging its digits

Given a number N, the task is to find the largest number less than or equal to the given number N such that on rearranging its digits it can become prime.

Examples:

Input : N = 99 
Output : 98
Explanation : We can rearrange the digits of 
98 to 89 and 89 is a prime number. 

Input : N = 84896
Output : 84896
Explanation : We can rearrange the digits of 
84896 to 46889 which is a prime number.

Below is the algorithm to find such a largest number num <= N such that digits of num can be rearranged to get a prime number:



Preprocessing Step: Generate a list of all the prime numbers less than or equal to given number N. This can be done efficiently using the sieve of Eratosthenes.

Main Steps: The main idea is to check all numbers from N to 1, if any of the number can be reshuffled to form a prime. The first such number found will be the answer.

To do this, run a loop from N to 1 and for every number:

  1. Extract the digits of the given number and store it in a vector.
  2. Sort this vector to get the smallest number which can be formed using these digits.
  3. For each permutation of this vector, we would form a number and check whether the formed number is prime or not. Here we make use of the Preprocessing step.
  4. If it is prime then we stop the loop and this is our answer.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find a number less than
// or equal to N such that rearranging
// the digits gets a prime number
  
#include <bits/stdc++.h>
using namespace std;
  
// Preprocessed vector to store primes
vector<bool> prime(1000001, true);
  
// Function to generate primes using
// sieve of eratosthenese
void sieve()
{
    // Applying sieve of Eratosthenes
    prime[0] = prime[1] = false;
  
    for (long long i = 2; i * i <= 1000000; i++) {
  
        if (prime[i]) {
            for (long long j = i * i; j <= 1000000; j += i)
                prime[j] = false;
        }
    }
}
  
// Function to find a number less than
// or equal to N such that rearranging
// the digits gets a prime number
int findNumber(int n)
{
    vector<int> v;
    bool flag = false;
  
    int num;
  
    // Run loop from n to 1
    for (num = n; num >= 1; num--) {
  
        int x = num;
  
        // Clearing the vector
        v.clear();
  
        // Extracting the digits
        while (x != 0) {
            v.push_back(x % 10);
  
            x /= 10;
        }
  
        // Sorting the vector to make smallest
        // number using digits
        sort(v.begin(), v.end());
  
        // Check all permutation of current number
        // for primality
        while (1) {
            long long w = 0;
  
            // Traverse vector to for number
            for (auto u : v)
                w = w * 10 + u;
  
            // If prime exists
            if (prime[w]) {
  
                flag = true;
                break;
            }
  
            if (flag)
                break;
  
            // generating next permutation of vector
            if (!next_permutation(v.begin(), v.end()))
                break;
        }
  
        if (flag)
            break;
    }
  
    // Required number
    return num;
}
  
// Driver Code
int main()
{
    sieve();
  
    int n = 99;
    cout << findNumber(n) << endl;
  
    n = 84896;
    cout << findNumber(n) << endl;
  
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python 3 Program to find a number less than
# or equal to N such that rearranging
# the digits gets a prime number
from math import sqrt
  
def next_permutation(a):
      
    # Generate the lexicographically 
    # next permutation inplace.
  
    # Generation_in_lexicographic_order
    # Return false if there is no next permutation.
  
    # Find the largest index i such that 
    # a[i] < a[i + 1]. If no such index exists, 
    # the permutation is the last permutation
    for i in reversed(range(len(a) - 1)):
        if a[i] < a[i + 1]:
            break # found
    else: # no break: not found
        return False # no next permutation
  
    # Find the largest index j greater than i
    # such that a[i] < a[j]
    j = next(j for j in reversed(range(i + 1, len(a))) 
                                      if a[i] < a[j])
  
    # Swap the value of a[i] with that of a[j]
    a[i], a[j] = a[j], a[i]
  
    # Reverse sequence from a[i + 1] up to and
    # including the final element a[n]
    a[i + 1:] = reversed(a[i + 1:])
    return True
  
# Preprocessed vector to store primes
prime = [True for i in range(1000001)]
  
# Function to generate primes using
# sieve of eratosthenese
def sieve():
      
    # Applying sieve of Eratosthenes
    prime[0] = False
    prime[1] = False
  
    for i in range(2,int(sqrt(1000000)) + 1, 1):
        if (prime[i]):
            for j in range(i * i, 1000001, i):
                prime[j] = False
  
# Function to find a number less than
# or equal to N such that rearranging
# the digits gets a prime number
def findNumber(n):
    v = []
    flag = False
      
    # Run loop from n to 1
    num = n
    while(num >= 1):
        x = num
          
        v.clear()
  
        # Extracting the digits
        while (x != 0):
            v.append(x % 10)
  
            x = int(x / 10)
  
        # Sorting the vector to make smallest
        # number using digits
        v.sort(reverse = False)
  
        # Check all permutation of current number
        # for primality
        while (1):
            w = 0
  
            # Traverse vector to for number
            for u in v:
                w = w * 10 + u
  
            # If prime exists
            if (prime[w]):
                flag = True
                break
  
            if (flag):
                break
  
            # generating next permutation of vector
            if (next_permutation(v) == False):
                break
  
        if (flag):
            break
          
        num -= 1
  
    # Required number
    return num
  
# Driver Code
if __name__ == '__main__':
    sieve()
  
    n = 99
    print(findNumber(n))
  
    n = 84896
    print(findNumber(n))
  
# This code is contributed by
# Surendra_Gangwar

chevron_right


Output:

98
84896


My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : SURENDRA_GANGWAR