Package ket

Source Code of ket.Factorize

// Wrong place: move to a more appropriate location.
package ket;

import java.util.*;

import ket.math.Token;
import ket.math.Branch;
import ket.math.Argument;

import ket.math.Function;


/**
* Factorize given numbers into a vector of primes, retaining prime numbers
* between calculations as they are required.
*/
public class Factorize {

  Vector<Argument> terms;
  static final Primes primes = new Primes(); // TODO: Convert to a static, lazy-sequence.
  int powersOfTen;
  int n;

  private Factorize(int n) {
    this.terms = new Vector<Argument>();
    this.n = n;
    this.powersOfTen = 0;
  }

  /**
   * Return a prime integer value or a product of factors.  Tens can
   * optionally post-multiply the other factors for use in scientific
   * notation.  Null is returned if n can't be factorized (n<2).
   */
  public static Argument factorize(int n, boolean gatherTens) {
    if (n<2) {
      return null;
    } else if (n < Primes.MAX_PRIME) {
      primes.calcPrimes(n); // TODO: Should this be n or (int) Math.sqrt(n) ?
    }
    Factorize factorize = new Factorize(n);
    if (gatherTens)
      factorize.calcPowersOfTen();
    factorize.prependFactors();
    if (gatherTens)
      factorize.appendTens();
    return factorize.termsToBranch();
  }

  /**
   * Return the largest common divisor of the given integer pair
   * (defaulting to 1).  Integers may be negative as their signs are
   * ignored.
   */
  public static int findCommonDivisor(int a, int b) {
    a = positive(a);
    b = positive(b);
    for (int i=min(a,b); i>1; i--) {
      if (a%i==0 && b%i==0) {
        return i;
      }
    }
    return 1;
  }
 
  private static int min(int a, int b) {
    return a<b ? a : b;
  }

  private static int positive(int x) {
    return x>0 ? x : -x;
  }

  private void calcPowersOfTen() {
    while (n%10==0) {
      n /= 10;
      powersOfTen += 1;
    }
  }

  // Append terms of ten if the factors exist.
  private void appendTens() {
    if (powersOfTen>0) {
      terms.add(toPower(10, powersOfTen));
    }
  }

  /**
   * Find the next factor which can be appended more than once, add it to
   * the given list of factors, and return n/fractions.
   */
  private int findNextFactor(int n) {
    for (int p : primes.getPrimes()) {
      int count = 0;
      while (n%p==0 && n>1) {
        n /= p;
        count += 1;
      }
      if (count>0) {
        terms.add( toPower(p, count) );
        return n;
      }
    }
    return -1;
  }

  private void prependFactors() {
    if (n<=Primes.MAX_PRIME && primes.isPrime(n)) {
      // Look for factors unless it is too large or prime.
      while (n>1) {
        n = findNextFactor(n);
      }
    } else {
      // Otherwise keep what is left of the number.
      terms.add(new Token(n));
    }
  }

  private Argument termsToBranch() {
    switch (terms.size()) {
      case 0:
        return null;

      case 1:
        return terms.firstElement();

      default:
        Branch power = new Branch(Function.TIMES);
        for (Argument product : terms) {
          power.append(product);
        }
        return power;
    }
  }

  private Argument toPower(int mantissa, int exponent) {
    Token m = new Token(mantissa);
    if (exponent>1) {
      Token e = new Token(exponent);
      return new Branch(Function.POWER, m, e);
    } else {
      return m;
    }
  }
}
TOP

Related Classes of ket.Factorize

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.