Removing a number from array to make it Geometric Progression

Given an array arr[] of N positive elements, the task is to find whether it is possible to convert this array into Geometric Progression (GP) by removing at-most one element. If yes, then find index of the number removing which converts the array into a geometric progression.
Special Cases :
1) If whole array is already in GP, then return any index.
2) If it is not possible to convert array into GP, then print “Not possible”.

Examples:

Input  : arr[] = [2, 4, 8, 24, 16, 32]
Output : 3
Number to remove is arr[3], i.e., 24
After removing 24 array will be [2, 4, 8, 16, 32] which 
is a GP with starting value 2 and common ratio 2.

Input  : arr[] = [2, 8, 30, 60]
Output : Not Possible

We can solve this problem by handling some special cases and then finding the pivot element, removing which makes array a GP. First we will check that our pivot element is first or second element, if not then the multiplier between them will be common ration of our GP, if yes then we found our solution.
Once we get common ratio of GP, we can check array element with this ratio, if this ratio violates at some index, then we skip this element and check from next index whether it is a continuation of previous GP or not.
In below code a method isGP is implemented which checks array to be GP after removing element at index ‘index’. This method is written for special case handling of first, second and last element.
Please see below code for better understanding.

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

//  C/C++ program to find the element removing which
// complete array becomes a GP
#include <bits/stdc++.h>
using namespace std;
#define EPS 1e-6
  
//  Utitilty method to compare two double values
bool fEqual(double a, double b)
{
    return (abs(a - b) < EPS);
}
  
//  Utility method to check, after deleting arr[ignore],
//  remaining array is GP or not
bool isGP(double arr[], int N, int ignore)
{
    double last = -1;
    double ratio = -1;
  
    for (int i = 0; i < N; i++)
    {
        //  check ratio only if i is not ignore
        if (i != ignore)
        {
            //  last will be -1 first time
            if (last != -1)
            {
                //  ratio will be -1 at first time
                if (ratio == -1)
                    ratio = (double)arr[i] / last;
  
                //  if ratio is not constant return false
                else if (!fEqual(ratio, (double)arr[i] / last))
                    return false;
            }
            last = arr[i];
        }
    }
    return true;
}
  
//  method return value removing which array becomes GP
int makeGPbyRemovingOneElement(double arr[], int N)
{
    /*  solving special cases separately */
    //  Try removing first element
    if (isGP(arr, N, 0))
        return 0;
  
    //  Try removing second element
    if (isGP(arr, N, 1))
        return 1;
  
    //  Try removing last element
    if (isGP(arr, N, N-1))
        return (N-1);
  
    /*  now we know that first and second element will be
        part of our GP so getting constant ratio of our GP */
    double ratio = (double)arr[1]/arr[0];
    for (int i = 2; i < N; i++)
    {
        if (!fEqual(ratio, (double)arr[i]/arr[i-1]))
        {
             /* At this point, we know that elements from arr[0]
               to arr[i-1] are in GP. So arr[i] is the element
               removing which may make GP.  We check if removing
               arr[i] actually makes it GP or not. */
            return (isGP(arr+i-2, N-i+2, 2))? i : -1;
         }
    }
  
    return -1;
}
  
//  Driver code to test above method
int main()
{
    double arr[] = {2, 4, 8, 30, 16};
    int N = sizeof(arr) / sizeof(arr[0]);
  
    int index = makeGPbyRemovingOneElement(arr, N);
    if (index == -1)
        cout << "Not possible\n";
    else
        cout << "Remove " << arr[index]
             << " to get geometric progression\n";
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the element removing which 
// complete array becomes a GP 
import java.util.*;
  
class GFG {
  
    final static double EPS = (double) 1e-6;
  
    // Utitilty method to compare two double values
    static boolean fEqual(double a, double b) {
        return (Math.abs(a - b) < EPS);
    }
  
    // Utility method to check, after deleting arr[ignore],
    // remaining array is GP or not
    static boolean isGP(double[] arr, int N, int ignore) {
        double last = -1;
        double ratio = -1;
  
        for (int i = 0; i < N; i++) {
  
            // check ratio only if i is not ignore
            if (i != ignore) {
  
                // last will be -1 first time
                if (last != -1) {
  
                    // ratio will be -1 at first time
                    if (ratio == -1)
                        ratio = (double) arr[i] / last;
  
                    // if ratio is not constant return false
                    else if (!fEqual(ratio, (double) arr[i] / last))
                        return false;
                }
                last = arr[i];
            }
        }
        return true;
    }
  
    // method return value removing which array becomes GP
    static int makeGPbyRemovingOneElement(double[] arr, int N) {
  
        /* solving special cases separately */
        // Try removing first element
        if (isGP(arr, N, 0))
            return 0;
  
        // Try removing second element
        if (isGP(arr, N, 1))
            return 1;
  
        // Try removing last element
        if (isGP(arr, N, N - 1))
            return (N - 1);
  
        /*
        * now we know that first and second element will be
        * part of our GP so getting constant ratio of our GP
        */
        double ratio = (double) arr[1] / arr[0];
        for (int i = 2; i < N; i++) {
            if (!fEqual(ratio, (double) arr[i] / arr[i - 1])) {
                /*
                * At this podouble, we know that elements from arr[0]
                * to arr[i-1] are in GP. Soarr[i] is the element
                * removing which may make GP. We check if removing
                * arr[i] actually makes it GP or not.
                */
                double[] temp = new double[N - i + 2];
                int k = 0;
                for (int j = i - 2; j < N; j++) {
                    temp[k++] = arr[j];
                }
                return (isGP(temp, N - i + 2, 2)) ? i : -1;
            }
        }
  
        return -1;
    }
  
    // Driver Code
    public static void main(String[] args) {
  
        double arr[] = { 2, 4, 8, 30, 16 };
        int N = arr.length;
  
        int index = makeGPbyRemovingOneElement(arr, N);
        if (index == -1)
            System.out.println("Not possible");
        else
            System.out.println("Remove " + arr[index] +
                        " to get geometric progression");
    }
}
  
// This code is contributed by
// sanjeev2552

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python program to find the element removing which
# complete array becomes a GP
  
EPS = 1e-7
  
# Utitilty method to compare two double values
def fEqual(a, b):
    return abs(a - b) < EPS
  
# Utility method to check, after deleting arr[ignore],
# remaining array is GP or not
def isGP(arr, N, ignore):
    last = -1
    ratio = -1
  
    for i in range(N):
  
        # check ratio only if i is not ignore
        if i != ignore:
  
            # last will be -1 first time
            if last != -1:
  
                # ratio will be -1 at first time
                if ratio == -1:
                    ratio = arr[i] / last
  
                    # if ratio is not constant return false
                elif not fEqual(ratio, arr[i] / last):
                    return False
            last = arr[i]
  
    return True
  
# Method return value removing which array becomes GP
def makeGPbyRemovingOneElement(arr, N):
  
    # Solving special cases separately
    # Try removing first element
    if isGP(arr, N, 0):
        return 0
  
    # Try removing second element
    if isGP(arr, N, 1):
        return 1
  
    # Try removing last element
    if isGP(arr, N, N - 1):
        return N - 1
  
    # now we know that first and second element will be
    # part of our GP so getting constant ratio of our GP
    ratio = arr[1] / arr[0]
  
    for i in range(2, N):
        if not fEqual(ratio, arr[i] / arr[i - 1]):
  
            # At this point, we know that elements from arr[0]
            # to arr[i-1] are in GP. So arr[i] is the element
            # removing which may make GP. We check if removing
            # arr[i] actually makes it GP or not.
            return i if isGP(arr[i - 2:], N - i + 2, 2) else -1
  
    return -1
  
# Driver Code
if __name__ == "__main__":
    arr = [2, 4, 8, 30, 16]
    N = len(arr)
  
    index = makeGPbyRemovingOneElement(arr, N)
  
    if index == -1:
        print("Not Possible")
    else:
        print("Remove %d to get geometric progression" % arr[index])
  
# This code is contributed by
# sanjeev2552

chevron_right



Output:



Remove 30 to get geometric progression

This article is contributed by Utkarsh Trivedi. 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 write comments if you find anything incorrect, or you want to share more information about the topic discussed above.

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Improved By : sanjeev2552

Article Tags :
Practice Tags :


Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.