78 lines
2.5 KiB
Java
78 lines
2.5 KiB
Java
package com.fabiosalvini.permutations;
|
|
|
|
import org.junit.jupiter.params.ParameterizedTest;
|
|
import org.junit.jupiter.params.provider.MethodSource;
|
|
|
|
import java.util.*;
|
|
import java.util.function.Consumer;
|
|
import java.util.stream.Stream;
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
|
|
|
|
|
public class PermutationsGeneratorTest {
|
|
|
|
/**
|
|
* Generate a stream of arrays to be used in parametrized tests.
|
|
*/
|
|
@SuppressWarnings("unused")
|
|
private static Stream<long[]> elementsGenerator() {
|
|
List<long[]> elementsList = new LinkedList<>();
|
|
ArrayList<Long> elements = new ArrayList<>();
|
|
for (int i = 1; i < 10; i++) {
|
|
elements.add((long) i);
|
|
elementsList.add(
|
|
elements.stream().mapToLong(num -> num).toArray()
|
|
);
|
|
}
|
|
return elementsList.stream();
|
|
}
|
|
|
|
@ParameterizedTest
|
|
@MethodSource("elementsGenerator")
|
|
public void permutationsAreUniqueAndWithoutDuplicates(long[] elements) {
|
|
Set<String> permutations = new HashSet<>();
|
|
Consumer<long[]> consumer = (perm) -> {
|
|
assertFalse(hasDuplicates(perm), "Permutation contains duplicated elements");
|
|
String str = toString(perm);
|
|
assertFalse(permutations.contains(str), "Permutation " + str + " is duplicated");
|
|
permutations.add(str);
|
|
};
|
|
PermutationsGenerator generator = new PermutationsGenerator(elements, consumer);
|
|
generator.compute();
|
|
assertEquals(factorial(elements.length), permutations.size(), "Wrong permutations count");
|
|
}
|
|
|
|
/**
|
|
* Returns true if the input array has duplicated elements.
|
|
*/
|
|
private boolean hasDuplicates(long[] elements) {
|
|
return Arrays.stream(elements).distinct().toArray().length != elements.length;
|
|
}
|
|
|
|
/**
|
|
* Convert the input array into a string, so it can be stored in a Set to check for duplicates.
|
|
*/
|
|
private String toString(long[] elements) {
|
|
StringBuilder sb = new StringBuilder();
|
|
for (int i = 0; i < elements.length - 1; i++) {
|
|
sb.append(elements[i]);
|
|
sb.append(",");
|
|
}
|
|
sb.append(elements[elements.length - 1]);
|
|
return sb.toString();
|
|
}
|
|
|
|
/**
|
|
* Compute n!.
|
|
*/
|
|
private long factorial(int n) {
|
|
long factorial = 1;
|
|
for (int i = 1; i <= n; i++) {
|
|
factorial = factorial * i;
|
|
}
|
|
return factorial;
|
|
}
|
|
}
|