credimi-challenge-permutations/src/test/java/com/fabiosalvini/permutations/PermutationsGeneratorTest.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;
}
}