First save all combinations with repetitions in a cell array. In order to do that, just use nmultichoosek.
v = 1 : 8;
combs = cell(length(v),0);
for i = v
combs{i} = nmultichoosek(v,i);
end
In this way, each element of combs
contains a matrix where each row is a combination. For instance, the i-th
row of combs{4}
is a combination of four numbers.
Now you need to check the sum. In order to do that to all the combinations, use cellfun
sums = cellfun(@(x)sum(x,2),combs,'UniformOutput',false);
sums
contains the vectors with the sum of all combinations. For
instance, sums{4}
has the sum of the number in combination combs{4}
.
The next step is check for the fixed sum.
fixed_sum = 10;
indices = cellfun(@(x)x==fixed_sum,sums,'UniformOutput',false);
indices
contains arrays of logical values, telling if the combination satisfies the fixed sum. For instance, indices{4}(1)
tells you if the first combination with 4 numbers sums to fixed_sum
.
Finally, retrieve all valid combinations in a new cell array, sorting them at the same time.
valid_combs = cell(length(v),0);
for i = v
idx = indices{i};
c = combs{i};
valid_combs{i} = sortrows(c(idx,:));
end
valid_combs
is a cell similar to combs
, but with only combinations that sum up to your desired value, and sorted by the number of numbers used: valid_combs{1}
has all valid combinations with 1 number, valid_combs{2}
with 2 numbers, and so on. Also, thanks to sortrows
, combinations with the same amount of numbers are also sorted. For instance, if fixed_sum = 10
then valid_combs{8}
is
1 1 1 1 1 1 1 3
1 1 1 1 1 1 2 2
This code is quite efficient, on my very old laptop I am able to run it in 0.016947 seconds.