import java.math.BigInteger; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; class Permutations { var permutationA = new Permutation<>(1, 2, 3, 4, 5, 6, 7, 8, 9); var permutationB = new Permutation<>(1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4); } static class Permutation<T extends Comparable<T>> { private final List<T> valueList; private final List<T> distinctValueList; private final int[] distinctValueCounts; @SuppressWarnings("unchecked") Permutation(T... values) { Objects.requireNonNull(values); // valueList = Arrays.stream(values).sorted().toList(); valueList = Collections.unmodifiableList(Arrays.stream(values).sorted().collect(Collectors.toList())); // distinctValueList = valueList.stream().distinct().toList(); distinctValueList = Collections.unmodifiableList(valueList.stream().distinct().collect(Collectors.toList())); distinctValueCounts = distinctValueList.stream() .flatMap(x -> Stream.of(valueList.stream().filter(value -> value.equals(x)).count())) .mapToInt(count -> count.intValue()) .toArray(); } var numberOfPermutations = numberOfPermutations(distinctValueCounts); throw new IllegalArgumentException("Requires index >= 1 && index <= " + numberOfPermutations + ", but index = " + index); } BigInteger index; int[] distinctValueCounts; } void setDistinctValueCounts(int[] distinctValueCounts) { this.distinctValueCounts = distinctValueCounts; } NumberOfPermutationsTableData[] numberOfPermutationsTable; BigInteger iTableValueMax; void reset() { numberOfPermutationsTable = getNumberOfPermutationsTable(distinctValueCounts); } void setNextDistionctValuecounts(int iNumberOfPermutationsTable) { distinctValueCounts = numberOfPermutationsTable[iNumberOfPermutationsTable].distinctValueCounts; } boolean compare(int iNumberOfPermutationsTable) { var iTableValueMax = this.iTableValueMax.add(numberOfPermutationsTable[iNumberOfPermutationsTable].numberOfPermutations); if (index.compareTo(iTableValueMax) < 0) { index = index.subtract(this.iTableValueMax); return true; } this.iTableValueMax = iTableValueMax; return false; } }; states.setIndex(index); states.setDistinctValueCounts(distinctValueCounts); return IntStream.range(0, valueList.size()) .mapToObj(iResultList -> { states.reset(); var iNumberOfPermutationsTableOptional = IntStream.range(0, states.numberOfPermutationsTable.length) .filter(iNumberOfPermutationsTable -> states.compare(iNumberOfPermutationsTable)) .findFirst(); if (iResultList < valueList.size() - 1) { states.setNextDistionctValuecounts(iNumberOfPermutationsTableOptional.getAsInt()); } return distinctValueList.get(iNumberOfPermutationsTableOptional.getAsInt()); }) // .toList(); .collect(Collectors.toList()); } private int[] newDistinctValueCounts(int[] distinctValueCounts, int indexOfArrayToDecrement) { var clone = distinctValueCounts.clone(); --clone[indexOfArrayToDecrement]; return clone; } static class NumberOfPermutationsTableData { final int[] distinctValueCounts; this.numberOfPermutations = numberOfPermutations; this.distinctValueCounts = distinctValueCounts; } } private NumberOfPermutationsTableData[] getNumberOfPermutationsTable(int[] distinctValueCounts) { return IntStream.range(0, distinctValueCounts.length) .mapToObj(index -> { var newDistinctValueCounts = newDistinctValueCounts(distinctValueCounts, index); var numberOfPermutations = numberOfPermutations(newDistinctValueCounts); return new NumberOfPermutationsTableData(numberOfPermutations, newDistinctValueCounts); }) .toArray(NumberOfPermutationsTableData[]::new); } } .mapToObj(this::factorial) } if (n == 0) { } if (n < 1) { throw new IllegalArgumentException("Requires n >= 1 && n <= " + Integer.MAX_VALUE + ", but n = " + n); } return IntStream.rangeClosed(1, n).mapToObj(BigInteger::valueOf).reduce(BigInteger.ONE, (a, b) -> a.multiply(b)); } } }
Standard input is empty
[1, 2, 3, 4, 5, 6, 7, 8, 9] [1, 2, 3, 4, 5, 6, 7, 9, 8] [1, 2, 3, 4, 5, 6, 8, 7, 9] [4, 1, 6, 5, 8, 9, 7, 3, 2] [6, 8, 4, 7, 5, 3, 2, 1, 9] [9, 8, 7, 6, 5, 4, 3, 2, 1] [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4] [1, 1, 1, 2, 2, 2, 3, 3, 4, 3, 4, 4] [1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 3, 4] [2, 2, 2, 3, 3, 1, 4, 3, 4, 1, 1, 4] [3, 2, 4, 4, 2, 4, 3, 3, 1, 1, 1, 2] [4, 4, 4, 3, 3, 3, 2, 2, 2, 1, 1, 1]