If the order of the summands matters, so that [1,3]
and [3,1]
are not the same, then it is the integer composition. You can use the recursive method to build this sequence efficiently, but even so, it is too slow for large numbers. The number of permutations is 2(n-1)
, so I stopped at 27
.
Output of table n=[1-27]
, number of combinations, time milliseconds:
n: 1, composition: 1, time: 1
n: 2, composition: 2, time: 0
n: 3, composition: 4, time: 0
n: 4, composition: 8, time: 0
n: 5, composition: 16, time: 0
n: 6, composition: 32, time: 1
n: 7, composition: 64, time: 1
n: 8, composition: 128, time: 2
n: 9, composition: 256, time: 4
n: 10, composition: 512, time: 7
n: 11, composition: 1024, time: 14
n: 12, composition: 2048, time: 24
n: 13, composition: 4096, time: 24
n: 14, composition: 8192, time: 1
n: 15, composition: 16384, time: 3
n: 16, composition: 32768, time: 6
n: 17, composition: 65536, time: 11
n: 18, composition: 131072, time: 22
n: 19, composition: 262144, time: 46
n: 20, composition: 524288, time: 87
n: 21, composition: 1048576, time: 174
n: 22, composition: 2097152, time: 368
n: 23, composition: 4194304, time: 768
n: 24, composition: 8388608, time: 1635
n: 25, composition: 16777216, time: 3040
n: 26, composition: 33554432, time: 9015
n: 27, composition: 67108864, time: 45804
Java 7 code:
public static void main(String[] args) {
List<List<Integer>> list = composition(4, true);
for (List<Integer> comb : list)
System.out.println(comb);
for (int i = 1; i <= 27; i++) {
long time = System.currentTimeMillis();
List<List<Integer>> list1 = composition(i, false);
time = System.currentTimeMillis() - time;
System.out.println("n: " + String.format("%2d", i)
+ ", composition: " + String.format("%8d", list1.size())
+ ", time: " + String.format("%5d", time));
}
}
public static List<List<Integer>> composition(int n, boolean verbose) {
List<List<Integer>> list = new ArrayList<>();
composition(n, verbose ? "" : null, list, new ArrayList<Integer>());
return list;
}
public static void composition(
int i, String indent, List<List<Integer>> master, List<Integer> holder) {
if (indent != null && i == 0)
System.out.println(indent + "i=" + i + " comb=" + holder);
if (i == 0) master.add(holder);
for (int j = i; j >= 1; j--) {
ArrayList<Integer> temp = new ArrayList<>(holder);
temp.add(j);
if (indent != null)
System.out.println(indent + "i=" + i + ",j=" + j + " temp=" + temp);
composition(i - j, indent != null ? indent + " " : null, master, temp);
}
}
Output of recursive tree n=4
:
i=4,j=4 temp=[4]
i=0 comb=[4]
i=4,j=3 temp=[3]
i=1,j=1 temp=[3, 1]
i=0 comb=[3, 1]
i=4,j=2 temp=[2]
i=2,j=2 temp=[2, 2]
i=0 comb=[2, 2]
i=2,j=1 temp=[2, 1]
i=1,j=1 temp=[2, 1, 1]
i=0 comb=[2, 1, 1]
i=4,j=1 temp=[1]
i=3,j=3 temp=[1, 3]
i=0 comb=[1, 3]
i=3,j=2 temp=[1, 2]
i=1,j=1 temp=[1, 2, 1]
i=0 comb=[1, 2, 1]
i=3,j=1 temp=[1, 1]
i=2,j=2 temp=[1, 1, 2]
i=0 comb=[1, 1, 2]
i=2,j=1 temp=[1, 1, 1]
i=1,j=1 temp=[1, 1, 1, 1]
i=0 comb=[1, 1, 1, 1]
Output of the list n=4
:
[4]
[3, 1]
[2, 2]
[2, 1, 1]
[1, 3]
[1, 2, 1]
[1, 1, 2]
[1, 1, 1, 1]