import java.util.*; // https://en.wikipedia.org/wiki/Partition_(number_theory) public class Partitions { public static boolean nextPartition(List p) { int n = p.size(); if (n <= 1) return false; int s = p.remove(n - 1) - 1; int i = n - 2; while (i > 0 && p.get(i).equals(p.get(i - 1))) { s += p.remove(i); --i; } p.set(i, p.get(i) + 1); while (s-- > 0) { p.add(1); } return true; } public static List partitionByNumber(int n, long number) { List p = new ArrayList<>(); for (int x = n; x > 0; ) { int j = 1; while (true) { long cnt = partitionFunction(x)[x][j]; if (number < cnt) break; number -= cnt; ++j; } p.add(j); x -= j; } return p; } public static long numberByPartition(List p) { long res = 0; int sum = 0; for (int x : p) { sum += x; } for (int cur : p) { for (int j = 0; j < cur; j++) { res += partitionFunction(sum)[sum][j]; } sum -= cur; } return res; } public static void generateIncreasingPartitions(int[] p, int left, int last, int pos) { if (left == 0) { for (int i = 0; i < pos; i++) System.out.print(p[i] + " "); System.out.println(); return; } for (p[pos] = last + 1; p[pos] <= left; p[pos]++) generateIncreasingPartitions(p, left - p[pos], p[pos], pos + 1); } public static long countPartitions(int n) { long[] p = new long[n + 1]; p[0] = 1; for (int i = 1; i <= n; i++) { for (int j = i; j <= n; j++) { p[j] += p[j - i]; } } return p[n]; } public static long[][] partitionFunction(int n) { long[][] p = new long[n + 1][n + 1]; p[0][0] = 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { p[i][j] = p[i - 1][j - 1] + p[i - j][j]; } } return p; } public static long[][] partitionFunction2(int n) { long[][] p = new long[n + 1][n + 1]; p[0][0] = 1; for (int i = 1; i <= n; i++) { for (int j = 1; j <= i; j++) { for (int k = 0; k <= j; k++) { p[i][j] += p[i - j][k]; } } } return p; } // Usage example public static void main(String[] args) { System.out.println(7 == countPartitions(5)); System.out.println(627 == countPartitions(20)); System.out.println(5604 == countPartitions(30)); System.out.println(204226 == countPartitions(50)); System.out.println(190569292 == countPartitions(100)); List p = new ArrayList<>(); Collections.addAll(p, 1, 1, 1, 1, 1); do { System.out.println(p); } while (nextPartition(p)); int[] p1 = new int[8]; generateIncreasingPartitions(p1, p1.length, 0, 0); List list = partitionByNumber(5, 6); System.out.println(list); System.out.println(numberByPartition(list)); } }