// Bosquejo de un programa para manipular fracciones y su simplificacion
// Autor: Antonio Carrillo Ledesma
// http://mmc.geofisica.unam.mx/acl/


public class Fraccion {

   // Numerador de la fraccion
   private long P;
   // Denominador de la fraccion
   private long Q;
   // Arreglo que contendra a los primos
   static private long []Pr;
   // Numero de primos que contendra el arreglo de primos
   static final private int nPr = 1000;


   // Constructor nulo fraccion 0/1
   public Fraccion() {
      this(0, 1);
   }

   // Constructor con un objeto Fraccion
   public Fraccion (Fraccion a) {
      this(a.numerador(), a.denominador());
   }

   // Constructor con entero P Fraccion P/1
   public Fraccion (long p) {
      this(p, 1);
   }

   // Costructor con la fraccion P/Q
   public Fraccion (long p, long q) {
      P = p;
      Q = q;
      calculaPrimos();
   }



   // Calcula los primeros nPr primos por el algoritmos de criba de Eratostenes
   private void calculaPrimos() {

      int n, i, np;
      Pr = new long[nPr];

      // Guarda los primeros 2 primos
      Pr[0] = 2;
      Pr[1] = 3;
      np = 2;

      // Empieza la busqueda de primos a partir del numero 4
      n = 4;

      // Ciclo para buscar los primeros NPB primos
      while (np < nPr) {
         for (i = 0; i < np; i++) {
            if((n % Pr[i]) == 0) break;
         }
         if(i == np) {
            Pr[i] = n;
            np++;
         }
         n++;
      }
   }


   // Visualiza los primos encontrados
   public void visArregloPrimos() {
      System.out.println("Visualiza los primeros " + nPr + " primos");
      for (int i = 0; i < nPr; i++) System.out.println(Pr[i]);
      System.out.println("");
   }


   // Simplifica el numerador y denominador de la fraccion
   private void simplifica() {
      int i, sw;
      for (i = 0; i < nPr; i++) {
         do {
            sw = 0;
            if (Math.abs(P) < 2 || Q < 2) break;
            if((P % Pr[i] == 0) && (Q % Pr[i] == 0)) {
               P /= Pr[i];
               Q /= Pr[i];
               sw = 1;
            }
         } while(sw == 1);
      }

   }


   // Retorna el Numerador
   public long numerador() {
      return P;
   }

   // Retorna el denominador
   public long denominador() {
      return Q;
   }

   // Suma de fracciones con un operando
   public void suma(Fraccion a) {
      P = numerador() * a.denominador() + a.numerador() * denominador();
      Q = denominador() * a.denominador();
   }

   // Suma de fracciones con dos operandos
   public void suma(Fraccion a, Fraccion b) {
      P = a.numerador() * b.denominador() + b.numerador() * a.denominador();
      Q = a.denominador() * b.denominador();
   }

   public void resta(Fraccion a) {

   }

   public void resta(Fraccion a, Fraccion b) {

   }

   // Visualiza la Fraccion
   public void visualiza() {
      simplifica();
      System.out.print(P +  "/" + Q);
   }

   // Visualiza la fraccion y cambia de linea
   public void visualizaLN() {
      simplifica();
      System.out.println(P +  "/" + Q);
   }


   // Ejemplito de uso ...
   public static void main(String[] args) {
      Fraccion a, b, c, d;
      a = new Fraccion(1, 3);
      b = new Fraccion(2, 3);
      c = new Fraccion();
      d = new Fraccion();

      //c.VisArregloPrimos();


      System.out.println("Suma de dos operandos");
      a.visualiza();
      System.out.print(" + ");
      b.visualiza();
      System.out.print(" = ");
      c.suma(a, b);
      c.visualizaLN();


      System.out.println("Suma de un operando");
      a.visualiza();
      System.out.print(" + ");
      b.visualiza();
      System.out.print(" = ");
      a.suma(b);
      a.visualizaLN();

      System.out.println("Arreglo de Fraciones");
      int i, n = 10;
      // Inicializacion
      Fraccion e[] = new Fraccion [n];
      for (i = 0; i < n; i++) e[i] = new Fraccion(i + 1, n);
      // Uso
      for (i = 0; i < n; i++) {
         e[i].visualizaLN();
         d.suma(e[i]);
      }
      System.out.println("Suma del arreglo de Fraciones");
      d.visualizaLN();

   }
};



