Minimum changes required to make all Array elements Prime

Given an array of integers arr[], the task is to count the minimum number of changes required to convert each array element to its nearest prime.

Examples:

Input: arr[] = {4, 25, 13, 6, 20}
Output: 5
Explanation:

  • 1 increment required to convert 4 to its nearest prime 5.
  • 2 decrements required to convert 25 to its nearest prime 23.
  • 13 itself is a prime.
  • 1 increment required to convert 6 to its nearest prime 7.
  • 1 decrement required to convert 20 to its nearest prime 19.

Hence, required number of changes = 1 + 2 + 0 + 1 + 1 = 5

Input: arr[] = {1, 2, 9}
Output: 3
Explanation:



  • 1 increment required to convert 1 to its nearest prime 2.
  • 2 itself is a prime.
  • 2 increments required to convert 9 to its nearest prime 11.

Hence, required number of changes = 1 + 0 + 2 = 3

Naive Approach:
Traverse the array and for every array element, find its nearest prime number to its right starting from arr[i] + 1 and to its left starting from arr[i] – 1. Once computed, calculate their difference from arr[i] and consider the smaller difference. The Sum of all such differences gives the desired output.
Time Complexity: O(N * maxi2), where maxi denotes the maximum element in the array.

Efficient Approach:
This problem can be solved using Sieve of Eratosthenes. Follow the steps below to solve the problem:

  • Find the maximum element from the given array.
  • Let maxi be the maximum element present on the array. Generate all prime numbers in the range [1, 2*maxi] and store them.
  • Traverse the array and find the index of the next greater prime number for every array element using lower_bound, say x.
  • Calculate the absolute difference between arr[i] and primes[x] and between arr[i] and primes[x – 1].
  • Add the minimum of the two to ans.
  • After complete traversal of the array, print the final value of ans as the answer.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to implement
// the above approach
#include <bits/stdc++.h>
using namespace std;
  
// Function to generate all primes
vector<int> SieveOfEratosthenes(int n)
{
    bool prime[2 * n + 1];
    memset(prime, true, sizeof(prime));
  
    for (int p = 2; p * p <= 2 * n; p++) {
  
        // If p is a prime
        if (prime[p] == true) {
  
            // Mark all its multiples
            // as non-prime
            for (int i = p * p; i <= 2 * n;
                 i += p)
                prime[i] = false;
        }
    }
  
    vector<int> primes;
  
    // Store all prime numbers
    for (int p = 2; p <= 2 * n; p++)
        if (prime[p])
            primes.push_back(p);
  
    // Return the list of primes
    return primes;
}
  
// Function to calculate the
// minimum increments to
// convert every array elements
// to a prime
int minChanges(vector<int> arr)
{
    int n = arr.size();
    int ans = 0;
  
    // Extract maximum element
    // of the given array
    int maxi = *max_element(arr.begin(),
                            arr.end());
  
    vector<int> primes
        = SieveOfEratosthenes(maxi);
  
    for (int i = 0; i < n; i++) {
  
        // Extract the index which has
        // the next greater prime
        int x = lower_bound(primes.begin(),
                            primes.end(),
                            arr[i])
                - primes.begin();
  
        // Store the difference
        // between the prime and
        // the array element
        int minm = abs(primes[x]
                       - arr[i]);
  
        if (x > 1) {
            minm = min(minm,
                       abs(primes[x - 1]
                           - arr[i]));
        }
  
        ans += minm;
    }
    return ans;
}
  
// Driver Code
int main()
{
  
    vector<int> arr
        = { 4, 25, 13, 6, 20 };
  
    cout << minChanges(arr);
  
    return 0;
}

chevron_right


Output:

5

Time Complexity: O(log(log(N)) + O(NlogN)
Auxiliary Space: O(N)

competitive-programming-img




My Personal Notes arrow_drop_up


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.