PartitionsFacade.java :  » Math » algebra » ru » susu » algebra » partition » Java Open Source

Java Open Source » Math » algebra 
algebra » ru » susu » algebra » partition » PartitionsFacade.java
package ru.susu.algebra.partition;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import ru.susu.algebra.cache.SelfCleaningCache;
import ru.susu.algebra.pair.Pair;
import ru.susu.algebra.partition.filter.AllPartitionsFilter;

/**
 * @author akargapolov
 * @since: 01.03.2009
 */
public class PartitionsFacade
{
  private static SelfCleaningCache _cache = new SelfCleaningCache(10000);

  public static Partition getWithoutLastWithCache(Partition p)
  {
    String key = getWithoutLastKey(p);
    Partition res = (Partition) _cache.getValue(key);
    if (res == null)
    {
      Partition tmp = p.clone();
      tmp.remove(getLastNumber(tmp));
      res = getEqualsPartitionFromCache(tmp);
      _cache.put(key, res);
    }
    return res;
  }

  public static Partition getEqualsPartitionFromCache(Partition p)
  {
    PartitionsCacheConstructor constructor = new PartitionsCacheConstructor();
    List<Partition> partitions = constructor.getAscendingPartitions(p.getPresentedNumber(),
        new AllPartitionsFilter());
    // return partitions.get(Collections.binarySearch(partitions, p));
    return partitions.get(p.getOrderNumber());
  }

  public static Integer getLastNumber(Partition p)
  {
    Integer[] array = p.getArrayRepresentation();
    return array[array.length - 1];
  }

  public static List<Pair<Partition, Integer>> getPartitionsWithCache(Partition p1, Partition p2)
  {
    String key = getTwoPartitionsKey(p1, p2);
    List<Pair<Partition, Integer>> res = (List<Pair<Partition, Integer>>) _cache.getValue(key);
    if (res == null)
    {
      res = getPartitions(p1, p2);
      _cache.put(key, res);
    }
    return res;
  }

  private static List<Pair<Partition, Integer>> getPartitions(Partition p1, Partition p2)
  {
    ArrayList<Pair<Partition, Integer>> res = new ArrayList<Pair<Partition, Integer>>();
    int length = getLastNumber(p2);

    int arSize = p1.getLength();
    Integer[] array = p1.getArrayRepresentation();

    int i, j;

    for (i = 0; i < arSize; i++)
      for (j = 1; j <= array[i]; j++)
      {
        int len = getLength(array, arSize, i, j);
        if (len != length)
          continue;
        Integer[] b = removeCorner(array, arSize, i, j);
        Partition tmp = PartitionsFactory.createPartition(b);
        tmp = getEqualsPartitionFromCache(tmp);
        int footL = (length - (array[i] - j + 1)) % 2;
        res.add(new Pair<Partition, Integer>(tmp, footL));
      }

    return res;
  }

  private static int getLength(Integer[] array, Integer aSize, int i, int j)
  {
    int res = 0;
    res = array[i] - j;
    for (int k = 0; i - k >= 0 && array[i - k] >= j; k++)
      ++res;
    return res;
  }

  public static Integer[] removeCorner(Integer[] a, Integer aSize, int i, int j)
  {
    Integer bSize = aSize;
    Integer[] b = Arrays.copyOf(a, aSize);
    int k;
    for (k = i; k > 0 && b[k - 1] > j; k--)
      b[k] = b[k - 1] - 1;
    while (k >= 0 && b[k] >= j)
      b[k--] = j - 1;
    int d = 0;
    while (d < aSize && b[d] == 0)
      d++;

    if (d > 0)
    {
      for (k = 0; k + d < aSize; k++)
        b[k] = b[k + d];
      bSize -= d;
    }

    return Arrays.copyOf(b, bSize);
  }

  private static String DELIMETER = "_";

  private static String getWithoutLastKey(Partition p1)
  {
    StringBuilder builder = new StringBuilder();
    builder.append("withoutLast");
    builder.append(DELIMETER);
    builder.append(p1.getPresentedNumber().toString());
    builder.append(DELIMETER);
    builder.append(p1.getOrderNumber().toString());
    return builder.toString();
  }

  private static String getTwoPartitionsKey(Partition p1, Partition p2)
  {
    StringBuilder builder = new StringBuilder();
    builder.append("twoPartitions");
    builder.append(DELIMETER);
    builder.append(p1.getPresentedNumber().toString());
    builder.append(DELIMETER);
    builder.append(p1.getOrderNumber().toString());
    builder.append(DELIMETER);
    builder.append(getLastNumber(p2));
    return builder.toString();
  }

  public static Partition getAssociatedPartition(Partition p)
  {
    Integer[] array = p.getArrayRepresentation();
    if (array.length == 0)
      return p;
    Integer[] assArray = new Integer[array[array.length - 1]];
    Arrays.fill(assArray, Integer.valueOf(0));
    for (int index = 0; index < array.length; index++)
    {
      for (int j = 0; j < array[index]; j++)
        assArray[assArray.length - 1 - j]++;
    }
    Partition res = PartitionsFactory.createPartition(assArray);
    return PartitionsFacade.getEqualsPartitionFromCache(res);
  }

  public static BigInteger getMainHooksProduct(Partition p)
  {
    BigInteger res = BigInteger.valueOf(1);
    for (Integer hook : getMainHookLengths(p))
    {
      res = res.multiply(BigInteger.valueOf(hook));
    }
    return res;
  }

  public static Integer[] getMainHookLengths(Partition p)
  {
    List<Integer> hooks = new ArrayList<Integer>();
    Integer[] array = p.getArrayRepresentation();
    int i, j, k;
    j = 1;
    for (i = array.length - 1; i >= 0; i--)
    {
      if (j > array[i])
        break;
      for (k = 0; i - k >= 0 && array[i - k] >= j; k++)
        ;
      hooks.add(array[i] - j + k);
      j++;
    }
    Integer[] result = new Integer[hooks.size()];
    hooks.toArray(result);
    return result;
  }

  public static boolean isAlternatingSqrtCharacter(Partition p1, Partition p2)
  {
    Integer[] hooks = getMainHookLengths(p1);
    Arrays.sort(hooks);
    return Arrays.equals(hooks, p2.getArrayRepresentation());
  }

  public static BigInteger getElementsProduct(Partition p1)
  {
    BigInteger res = BigInteger.ONE;
    for (Integer item : p1.getArrayRepresentation())
    {
      res = res.multiply(BigInteger.valueOf(item));
    }
    return res;
  }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.