I am trying to generate all possible combinations of certain values in an array of 15 which add up to 50.
$a = [3, 4, 1, 2, 5]
print $a.repeated_permutation(15).to_a
In this case,
[2,2,2,2,4,4,4,4,4,4,4,4,4,3,3]
[2,2,2,4,2,4,4,4,4,4,4,4,4,3,3]
[2,2,4,2,2,4,4,4,4,4,4,4,4,3,3]
are all possible answers.
After some investigation I realize the code to do this is a bit over my head, but I will leave the question up if it might help someone else.
For some reference as to what I am working on, Project Euler, problem 114. It's pretty difficult, and so I am attempting to solve only a single case where my 50-space-long grid is filled only with 3-unit-long blocks. The blocks must be separated by at least one blank, so I am counting the blocks as 4. This (with some tweaking, which I have left out as this is confusing enough already) allows for twelve blocks plus three single blanks, or a maximum of fifteen elements.
Approach
I think recursion is the way to go here, where your recursive method looks like this:
where
nis the number of elements required; andtis the required total.If we let
@arrbe the array of integers you are given,recurse(n,t)returns an array of all permutations ofnelements from@arrthat sum tot.Assumption
I have assumed that the elements of
@arrare non-negative integers, sorted by size, but the method can be easily modified if it includes negative integers (though performance will suffer). Without loss of generality, we can assume the elements of@arrare unique, sorted by increasing magnitude.Code
Examples
Improvement
We can do better, however, by first computing all combinations, and then computing the permutations of each of those combinations.
We can then compute the permutations from the combinations:
We can approximate the number of permutations for
(15,50)(it will be somewhat high becauseuniqis not applied):That is, the result has about 1,600 digits. What platform will you be running this on?