import java.util.*; public class Permutations { public static boolean nextPermutation(int[] p) { for (int a = p.length - 2; a >= 0; --a) if (p[a] < p[a + 1]) for (int b = p.length - 1; ; --b) if (p[b] > p[a]) { int t = p[a]; p[a] = p[b]; p[b] = t; for (++a, b = p.length - 1; a < b; ++a, --b) { t = p[a]; p[a] = p[b]; p[b] = t; } return true; } return false; } public static int[] permutationByNumber(int n, long number) { long[] fact = new long[n]; fact[0] = 1; for (int i = 1; i < n; i++) { fact[i] = i * fact[i - 1]; } int[] p = new int[n]; int[] free = new int[n]; for (int i = 0; i < n; i++) { free[i] = i; } for (int i = 0; i < n; i++) { int pos = (int) (number / fact[n - 1 - i]); p[i] = free[pos]; System.arraycopy(free, pos + 1, free, pos, n - 1 - pos); number %= fact[n - 1 - i]; } return p; } public static long numberByPermutation(int[] p) { int n = p.length; long[] fact = new long[n]; fact[0] = 1; for (int i = 1; i < n; i++) { fact[i] = i * fact[i - 1]; } long res = 0; for (int i = 0; i < n; i++) { int a = p[i]; for (int j = 0; j < i; j++) { if (p[j] < p[i]) { --a; } } res += a * fact[n - 1 - i]; } return res; } public static void generatePermutations(int[] p, int depth) { int n = p.length; if (depth == n) { System.out.println(Arrays.toString(p)); return; } for (int i = 0; i < n; i++) { if (p[i] == 0) { p[i] = depth; generatePermutations(p, depth + 1); p[i] = 0; } } } public static long nextPermutation(long x) { long s = x & -x; long r = x + s; long ones = x ^ r; ones = (ones >> 2) / s; return r | ones; } public static List> decomposeIntoCycles(int[] p) { int n = p.length; boolean[] vis = new boolean[n]; List> res = new ArrayList<>(); for (int i = 0; i < n; i++) { if (vis[i]) continue; int j = i; List cur = new ArrayList<>(); do { cur.add(j); vis[j] = true; j = p[j]; } while (j != i); res.add(cur); } return res; } // Usage example public static void main(String[] args) { // print all permutations method 1 generatePermutations(new int[2], 1); // print all permutations method 2 int[] p = {0, 1, 2}; int cnt = 0; do { System.out.println(Arrays.toString(p)); if (!Arrays.equals(p, permutationByNumber(p.length, numberByPermutation(p))) || cnt != numberByPermutation(permutationByNumber(p.length, cnt))) throw new RuntimeException(); ++cnt; } while (nextPermutation(p)); System.out.println(5 == numberByPermutation(p)); System.out.println(Arrays.equals(new int[]{1, 0, 2}, permutationByNumber(3, 2))); System.out.println(0b1101 == nextPermutation(0b1011)); System.out.println(decomposeIntoCycles(new int[]{0, 2, 1, 3})); } }