package de.skuzzle.polly.tools.math;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class Permutator {
public final static int MAX_FACULTY_SIZE = 10;
public static int faculty(int n) {
if (n < 2) {
return 1;
}
return n * faculty(n - 1);
}
public static <T extends Comparable<T>> void nextPermutation(ArrayList<T> seq) {
if (seq.size() < 2) {
return;
}
int i = seq.size() - 2;
for (; i >= 0 && seq.get(i).compareTo(seq.get(i + 1)) > 0; --i);
if (i >= 0) {
int j = seq.size() - 1;
for (; seq.get(j).compareTo(seq.get(i)) <= 0; --j);
swap(seq, i, j);
}
reverse(seq, i + 1, seq.size() - 1);
}
private static <T> void swap(ArrayList<T> list, int i, int j) {
T tmp = list.get(i);
list.set(i, list.get(j));
list.set(j, tmp);
}
private static <T> void reverse(ArrayList<T> list, int l, int r) {
while (l < r) {
swap(list, l++, r--);
}
}
public static <T extends Comparable<T>> void nextPermutation(T[] seq) {
if (seq.length < 2) {
return;
}
int i = seq.length - 2;
for (; i >= 0 && seq[i].compareTo(seq[i + 1]) > 0; --i);
if (i >= 0) {
int j = seq.length - 1;
for (; seq[j].compareTo(seq[i]) <= 0; --j);
swap(seq, i, j);
}
reverse(seq, i + 1, seq.length - 1);
}
private static void reverse(Object[] arr, int l, int r) {
while (l < r) {
swap(arr, l++, r--);
}
}
public static <T> List<T[]> permute(T[] arr) {
if (arr.length > MAX_FACULTY_SIZE) {
throw new IllegalArgumentException("input arry too big");
}
List<T[]> results = new ArrayList<T[]>(faculty(arr.length));
permute(arr, 0, results);
return results;
}
@SuppressWarnings("unchecked")
public static <T> List<T[]> permute(List<T> list) {
return permute((T[]) list.toArray());
}
private static <T> void permute(T[] arr, int i, List<T[]> results) {
if (i == arr.length - 1) {
results.add(Arrays.copyOf(arr, arr.length));
return;
}
for (int j = i; j < arr.length; ++j) {
swap(arr, i, j);
permute(arr, i + 1, results);
swap(arr, i, j);
}
}
private static <T> void swap(T[] arr, int i, int j) {
T tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}