de.spricom.dessert.util.CombinationUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dessert-core Show documentation
Show all versions of dessert-core Show documentation
A library for unit-tests to check the dependencies between classes.
The newest version!
package de.spricom.dessert.util;
/*-
* #%L
* Dessert Dependency Assertion Library for Java
* %%
* Copyright (C) 2017 - 2023 Hans Jörg Heßmann
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* #L%
*/
import java.util.*;
public class CombinationUtils {
public static List> combinationsAsList(final List list) {
return asList(combinations(list), combinations(list.size()));
}
public static List> combinationsSortedAsList(final List list) {
return asList(combinationsSorted(list), combinationsSorted(list.size()));
}
private static List> asList(Iterable> iter, int capacity) {
List> results = new ArrayList>(capacity);
for (Pair tPair : iter) {
results.add(tPair);
}
return results;
}
public static Iterable> combinations(final List list) {
return new Iterable>() {
@Override
public Iterator> iterator() {
return both(pairs(list));
}
};
}
public static Iterable> combinationsSorted(final List list) {
return new Iterable>() {
@Override
public Iterator> iterator() {
return pairs(list);
}
};
}
public static List indexes(int size) {
Integer[] indexes = new Integer[size];
for (int i = 0; i < size; i++) {
indexes[i] = i;
}
return Arrays.asList(indexes);
}
private static Iterator> both(final Iterator> pairs) {
return new PermutationIterator() {
private Pair current;
@Override
public boolean hasNext() {
return current != null || pairs.hasNext();
}
@Override
public Pair next() {
if (current == null) {
current = pairs.next();
return current;
} else {
Pair other = new Pair(current.getRight(), current.getLeft());
current = null;
return other;
}
}
};
}
private static Iterator> pairs(final List list) {
final int sz = list.size();
if (sz < 2) {
throw new IllegalArgumentException("A list must contain at least 2 elements to create a permutation.");
}
if (sz == 2) {
return Collections.singleton(new Pair(list.get(0), list.get(1))).iterator();
}
return new PermutationIterator() {
private final T first = list.get(0);
private int index = 1;
private Iterator> rest;
@Override
public boolean hasNext() {
return index < sz || rest().hasNext();
}
@Override
public Pair next() {
if (index < sz) {
Pair result = new Pair(first, list.get(index));
index++;
return result;
}
return rest().next();
}
private Iterator> rest() {
if (rest == null) {
rest = pairs(list.subList(1, sz));
}
return rest;
}
};
}
public static int combinations(int n) {
return combinationsSorted(n) * 2;
}
public static int combinationsSorted(int n) {
return binominal(n, 2);
}
/**
* Calculates @{code factorial(n) / (factorial(k) * factorial(n - k))}.
*
* @param n number of different values
* @param k number of slots
* @return number of possible combinations
*/
public static int binominal(int n, int k) {
if (k * 2 > n) {
k = n - k;
}
int result = 1;
for (int i = 1; i <= k; i++) {
result = result * (n + 1 - i) / i;
}
return result;
}
public static int factorial(final int n) {
if (n < 0) {
throw new IllegalArgumentException("Factorial for negative numbers is not defined");
}
if (n <= 1) {
return 1;
}
long result = 1;
for (int i = 2; i <= n; i++) {
result = result * i;
if (result > Integer.MAX_VALUE) {
throw new IllegalArgumentException("Factorial of " + n + " does not fit into an integer.");
}
}
return (int)result;
}
static abstract class PermutationIterator implements Iterator> {
@Override
public void remove() {
throw new UnsupportedOperationException("Cannot remove elements from permutation.");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy