package org.matheclipse.combinatoric;

import java.util.Iterator;

/**
 * Generate an Iterable for permutations
 * 
 * See Permutation
 */
public class KPermutationsIterator implements Iterator, Iterable {

	final private int n;

	final private int k;

	final private int fPermutationsIndex[];

	final private int y[];

	private boolean first;

	private int h, i, m;

	final private int fCopiedResultIndex[];

	private int fResultIndex[];

	final IStepVisitor fHandler;

	/**
	 *
	 */
	public KPermutationsIterator(IStepVisitor handler, final int parts) {
		super();
		this.fHandler = handler;
		final int[] data = handler.getMultisetArray();
		n = data.length;
		k = parts;
		// f = fun;
		fPermutationsIndex = new int[n];
		y = new int[n];
		fCopiedResultIndex = new int[k];
		for (int a = 0; a < n; a++) {
			fPermutationsIndex[a] = data[a];
			y[a] = a;
		}
		if (k == n) {
			m = k - 1;
		} else {
			m = k;
		}
		first = true;
		i = m - 1;
		fResultIndex = nextBeforehand();
	}

	// public  KPermutationsIterable(final List fun, final int parts, final
	// int headOffset) {
	// super();
	// n = fun.size() - headOffset;
	// k = parts;
	//
	// fPermutationsIndex = new int[n];
	// y = new int[n];
	// fCopiedResultIndex = new int[k];
	// fPermutationsIndex[0] = 0;
	// y[0] = 0;
	// for (int a = 1; a < n; a++) {
	// if (fun.get(a + headOffset).equals(fun.get(a + headOffset - 1))) {
	// fPermutationsIndex[a] = fPermutationsIndex[a - 1];
	// } else {
	// fPermutationsIndex[a] = a;
	// }
	// y[a] = a;
	// }
	// if (k == n) {
	// m = k - 1;
	// } else {
	// m = k;
	// }
	// first = true;
	// i = m - 1;
	// fResultIndex = nextBeforehand();
	// }

	/**
	 *
	 */
	private final int[] nextBeforehand() {
		if (first) {
			first = false;
			return fPermutationsIndex;
		}
		do {
			if (y[i] < (n - 1)) {
				y[i] = y[i] + 1;
				if (fPermutationsIndex[i] != fPermutationsIndex[y[i]]) {
					// check fixpoint
					h = fPermutationsIndex[i];
					fPermutationsIndex[i] = fPermutationsIndex[y[i]];
					fPermutationsIndex[y[i]] = h;
					i = m - 1;
					return fPermutationsIndex;
				}
				continue;
			}
			do {
				h = fPermutationsIndex[i];
				fPermutationsIndex[i] = fPermutationsIndex[y[i]];
				fPermutationsIndex[y[i]] = h;
				y[i] = y[i] - 1;
			} while (y[i] > i);
			i--;
		} while (i != -1);
		return null;
	}

	public int[] next() {
		System.arraycopy(fResultIndex, 0, fCopiedResultIndex, 0, k);
		fResultIndex = nextBeforehand();
		return fCopiedResultIndex;
	}

	public boolean hasNext() {
		return fResultIndex != null;
	}

	public void remove() {
		throw new UnsupportedOperationException();
	}

	public Iterator iterator() {
		return this;
	}

	public boolean execute() {

		while (hasNext()) {
			final int[] actual = next();
			if (!fHandler.visit(actual)) {
				return false;
			}
		}
		return true;
	}
}

 

Ads help maintain this website.