Eliminar un número de una array para convertirlo en Progresión geométrica

Dada una array arr[] de N elementos positivos, la tarea es encontrar si es posible convertir esta array en P rogresión geométrica (GP) eliminando como máximo un elemento. En caso afirmativo, encuentre el índice de la eliminación del número que convierte la array en una progresión geométrica. 
Casos especiales: 
1) Si toda la array ya está en GP, ​​devuelva cualquier índice. 
2) Si no es posible convertir la array en GP, ​​imprima «No es posible».

Ejemplos: 

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

Podemos resolver este problema manejando algunos casos especiales y luego encontrando el elemento pivote, eliminando lo que hace que la array sea una GP. Primero, verificaremos que nuestro elemento pivote sea el primer o segundo elemento, si no, el multiplicador entre ellos será la proporción común de nuestro GP, si es así, encontramos nuestra solución. 
Una vez que obtengamos la relación común de GP, podemos verificar el elemento de array con esta relación, si esta relación viola algún índice, omitimos este elemento y verificamos desde el siguiente índice si es una continuación de GP anterior o no. 
En el siguiente código, se implementa un método isGP que verifica que la array sea GP después de eliminar el elemento en el índice ‘índice’. Este método está escrito para el manejo de casos especiales del primer, segundo y último elemento. 

Consulte el código a continuación para una mejor comprensión.

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
 
//  Utility 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;
}

Java

// 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;
 
    // Utility 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

Python3

# Python program to find the element removing which
# complete array becomes a GP
 
EPS = 1e-7
 
# Utility 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
                else if 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

C#

// C# program to find the element
// removing which complete array
// becomes a GP
using System;
  
class GFG{
  
static double EPS = (double)1e-6;
 
// Utility method to compare two
// double values
static bool 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 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
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)
        Console.Write("Not possible");
    else
        Console.Write("Remove " + arr[index] +
                      " to get geometric progression");
}
}
 
// This code is contributed by rutvik_56

Javascript

// JavaScript program to find the element removing which
// complete ar4ray becomes a GP
let EPS = 1e-5;
 
// Utility method to compare two double values
function fEqual(a, b)
{  
     
    return Math.abs(Math.fround(a)  - Math.fround(b)) < Math.fround(EPS);
}
 
// Utility method to check, after deleting arr[ignore],
// remaining array is GP or not
function isGP(arr, N, ignore)
{
    var last = -1, ratio = -1;
 
    for (var 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 = (arr[i] / last);
 
                // if ratio is not constant return false
                else if  (!(fEqual(ratio, arr[i] / last)))
                    return false;
            }
            last = arr[i];
        }
    }
 
    return true;
}
 
// Method return value removing which array becomes GP
function 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
    var ratio = parseFloat(arr[1] / arr[0]);
 
    for (var i = 2; i < N; i++)
    {
        if  (!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.
            if (isGP(arr.slice(i - 2), N - i + 2, 2))
                return i
            return -1;
        }
    }
 
    return -1
}
 
 
//  Driver Code
 
let arr = [2, 4, 8, 30, 16];
let N = arr.length;
 
let index = makeGPbyRemovingOneElement(arr, N)
 
if (index == -1)
    console.log("Not Possible")
else
    console.log("Remove", arr[index], "to get geometric progression");
 
// This code is contributed by phasing17

Producción: 

Remove 30 to get geometric progression

Este artículo es una contribución de Utkarsh Trivedi . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
 

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *