// Clase para manipular polinomios
// Antonio Carrillo Ledesma

// Se define al polinomio por sus coeficientes, es decir
//    A0 + A1x^1 + ...+Anx^n
// Quedando el arreglo como
//    A0, A1, ... An

public class Poly {

   // Coeficientes del polinomio
   private double []C;
   // Guarda la dimension del arreglo de coeficientes
   static final private int Dim = 10;


   // Constructor de la clase
   public Poly(double []coef) {
      int i, n = coef.length;
      C = new double [Dim];
      for (i = 0; i < n; i++) C[i] = coef[i];
   }

   // Constructor de la clase
   public Poly(Poly a) {
      int i, n = a.dimension();
      C = new double [Dim];
      for (i = 0; i < n; i++) C[i] = a.coeficiente(i);
   }

   // Retorna los coeficientes del polinomio
   double coeficiente(int i) {
      if (i < Dim) return C[i];
      return 0.0;
   }

   // Retorna la dimension del arreglo de coeficientes
   int dimension() {
      return Dim;
   }

   // Devuelve el grado del polinomio contenido en el arreglo
   public int grado(double []a) {
      int i, g;
      g = a.length - 1 ;
      for (i = (a.length - 1); i > 0; i--) {
         if (a[i] == 0.0) g--;
         else return g;
      }
      return g;
   }

   // Devuelve el grado del polinomio
   public int grado(Poly a) {
      int i, g;
      g = a.C.length - 1;
      for (i = (a.C.length - 1); i > 0; i--) {
         if (a.coeficiente(i) == 0.0) g--;
         else return g;
      }
      return g;
   }


   // Visualiza el polinomio
   public void visualiza() {
      int i;

      for (i = 0; i < Dim; i++) {
         if (C[i] != 0.0) {
            System.out.print(" + ");
            System.out.print(C[i]);
            if (i == 0) continue;
            System.out.print("X^");
            System.out.print(i);
         }
      }
      System.out.println(" ");
   }


   // Suma el polinomio A y B
   public void suma(Poly a, Poly b) {
      int i;

      for (i = 0; i < Dim; i++)  C[i] = a.coeficiente(i) + b.coeficiente(i);
   }


   // Multiplica los polinomio A y B
   public void multiplica(Poly a, Poly b) {
      int i, j;
      // Inicializa el arreglo de trabajo
      for (i = 0; i < Dim; i++) C[i] = 0.0;
      // Realiza la multiplicacion
      for (i = 0; i < Dim / 2; i++) {
         for (j = 0; j < Dim / 2; j++) {
            C[i + j] += a.coeficiente(i) * b.coeficiente(j);
         }
      }
   }



   // Algoritmo de Euclides para polinomios
   public void aep(double []f, double []g, double q[], double []r) {
      int i, j, gg, gr;

      // Inicializo r y q
      for (i = 0; i < f.length; i++) {
         r[i] = f[i];
         q[i] = 0.0;
      }
      // Algoritmo de Euclides para polinomios
      gg = grado(g);
      gr = grado(r);
      while (gr >= gg) {
         q[gr - gg] = r[gr] / g[gg];
         for (j = 0; j <= gg; j++) r[gr - j] -= (g[gg - j] * q[gr - gg]);
         gg = grado(g);
         gr = grado(r);
      }
   }



   // Funcion Principal ....
   public static void main(String[] args) {
      int i, j;
      double A[] = {3.0, -4.0, 1.5};
      double B[] = {1.0, 1.0, 2.0};
      double C[] = new double [10];

      Poly a = new Poly(A);
      a.visualiza();
      Poly b = new Poly(B);
      b.visualiza();
      Poly c = new Poly(C);
      c.suma(a, b);
      c.visualiza();

   }
}


