package org.geogebra.common.kernel.prover; import java.util.HashSet; import java.util.Iterator; import java.util.Set; /** * Implementation of iterable combinations of a set. Based on * http://stackoverflow.com/a/7631893. * * @author Zoltan Kovacs <zoltan@geogebra.org> * * Usage: * * Set<Integer> a = new HashSet<Integer>(); a.add(1); a.add(2); * a.add(3); a.add(4); * * Combinations b = new Combinations(a,2); * * while (b.hasNext()) { Set c = (Set) b.next(); Log.debug(c); } */ public class Combinations implements Iterator<Object> { private Set<?> set; private int r, n; private int[] num; // representation with numbers private boolean done = false; private Object[] list; /** * Creates all combinations of a set of the given order * * @param inputSet * the input set * @param order * the order */ public Combinations(Set<?> inputSet, int order) { set = inputSet; n = inputSet.size(); r = order; if (n < r) { // in this case we don't have to do anything done = true; return; } num = new int[r]; for (int i = 0; i < r; i++) { num[i] = i + 1; } list = new Object[n]; list = set.toArray(); } @Override public boolean hasNext() { return !done; } @Override public Set<Object> next() { Set<Object> ret = new HashSet<Object>(); for (int i = 0; i < r; ++i) { ret.add(list[num[i] - 1]); } done = nextNum(); return ret; } private boolean nextNum() { int target = r - 1; num[target]++; if (num[target] > ((n - (r - target)) + 1)) { // Carry the One while (num[target] > ((n - (r - target)))) { target--; if (target < 0) { break; } } if (target < 0) { return true; } num[target]++; for (int i = target + 1; i < num.length; i++) { num[i] = num[i - 1] + 1; } } return false; } @Override public void remove() { // TODO Auto-generated method stub } }