Index: /lang/java/skypencil/trunk/src/jp/skypencil/util/math/Combination.java
===================================================================
--- /lang/java/skypencil/trunk/src/jp/skypencil/util/math/Combination.java (revision 35673)
+++ /lang/java/skypencil/trunk/src/jp/skypencil/util/math/Combination.java (revision 35673)
@@ -0,0 +1,73 @@
+package jp.skypencil.util.math;
+
+import java.math.BigInteger;
+import java.util.BitSet;
+import java.util.Iterator;
+
+/**
+ * @see http://ht.econ.kobe-u.ac.jp/~tanizaki/class/combinat/combinat.htm
+ * @author eller
+ */
+public class Combination implements Iterable<BitSet> {
+	private final int select;
+	private final int max;
+
+	public Combination(final int max, final int select) {
+		if (max <= 0 || select < 0 || max < select) {
+			throw new IllegalArgumentException();
+		}
+
+		this.max = max;
+		this.select = select;
+	}
+
+	@Override
+	public Iterator<BitSet> iterator() {
+		return new Iter(max, select);
+	}
+
+	private static class Iter implements Iterator<BitSet> {
+		private final BigInteger max;
+		private BigInteger value;
+
+		public Iter(int max, int select) {
+			this.max = BigInteger.valueOf(max);
+			this.value = BigInteger.ONE.shiftLeft(select).subtract(BigInteger.ONE);
+		}
+
+		@Override
+		public boolean hasNext() {
+			return value.compareTo(max) < 0;
+		}
+
+		@Override
+		public BitSet next() {
+			final BitSet result = new BitSet(max.intValue());
+			for (int i = 0; i < max.intValue(); ++i) {
+				if (value.testBit(i)) {
+					result.set(i);
+				}
+			}
+			value = after(value);
+			return result;
+		}
+
+		private BigInteger after(final BigInteger before) {
+			final BigInteger param1 = smallestBitOf(before);
+			final BigInteger param2 = param1.add(before);
+			final BigInteger param3 = smallestBitOf(param2);
+			final BigInteger param5 = param3.divide(param1).shiftRight(1);
+			return param5.subtract(BigInteger.ONE).add(param2);
+		}
+
+		private BigInteger smallestBitOf(final BigInteger source) {
+			final int lowestBit = source.getLowestSetBit();
+			return BigInteger.ONE.shiftLeft(lowestBit);
+		}
+
+		@Override
+		public void remove() {
+			throw new UnsupportedOperationException();
+		}
+	}
+}
