Removing a Number from Array to make It Geometric Progression using C++


We are given an array of elements. We need to find whether the elements in the array are in Geometric Progression (GP) or not after removing any 1 element from the array. We can run out the possibilities and with observations to figure out that the first element is fake, or the second element is fake, or these 2 elements will give the common ratio of the array.

After the common ratio is found, we can iterate on the array to see if all elements follow that rule. 2 base conditions would be to check if the first and second elements are fake or not.

Let us look at some input/output scenarios to get a better understanding of the method −

Assume the input given to the problem is already in geometric progression, so there is not a necessity to remove any element from the array −

Input: {1, 2, 4, 8, 16}
Result: Already in GP

Assume the input given to the problem is not in geometric progression, the output can be obtained in two ways; if removal of any element will not give us a geometric progression then the output is printed as “not possible” −

Input: {1, 2, 3, 4, 5, 6}
Result: Not Possible

Assume the input given to the problem is not in geometric progression, the output can be obtained in two ways; if removing one element will give us a geometric progression then the element to be removed is printed as the output −

Input: {1, 4, 5, 16, 64, 256}
Result: Remove 5

Example

Suppose we have an array such as [1,3,6,9,27,81], and the array would be in GP if we remove element 6 from it.

Following is a program to show the implementation of the same method in C++ −

#include <iostream> #include <vector> using namespace std; #define DOUBLE_COMPARE_LIMIT 1e-6 bool isEqual(double a, double b) { return (abs(a - b) < DOUBLE_COMPARE_LIMIT); } bool isGP(vector<double> arr, int index) { double previous = -1; double ratio = -1; for (int i = 0; i < arr.size(); i++) { if (i != index) { if (previous != -1) { if (ratio == -1) { ratio = arr[i] / previous; } else if (!isEqual(ratio, arr[i] / previous)) { return false; } } previous = arr[i]; } } return true; } int solve(vector<double> arr) { if(isGP(arr, -1)) return -2; if (isGP(arr, 0)) return 0; if (isGP(arr, 1)) return 1; double ratio = arr[1]/arr[0]; for (int i = 2; i < arr.size(); i++) { if (!isEqual(ratio, arr[i]/arr[i-1])){ return (isGP(arr, i))? i : -1; } } return -1; } int main() { vector<double> arr = {1,3,6,9,27,81}; int index = solve(arr); if (index == -1) { cout << "Not possible"; } else if(index == -2) { cout << "Already in GP"; } else { cout << "Remove " << arr[index]; } return 0; }

Output

Remove 6

The common ratio of the elements in the array becomes 3, and the starting element is 1. So the array becomes [1 3,9,27,81]

Conclusion

The above algorithm runs perfectly. This was a pure brute force and implementation problem. We used a function to compare float values because of overflow. We used floats because the common ratio can be in fractions. DOUBLE_COMPARE_LIMIT will compare the float values to a certain decimal place because we might have a long result or never ending decimal. Code it yourself once to better understand the problem.

Updated on: 10-Aug-2022

88 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements