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
n
is the number of elements required; andt
is the required total.If we let
@arr
be the array of integers you are given,recurse(n,t)
returns an array of all permutations ofn
elements from@arr
that sum tot
.Assumption
I have assumed that the elements of
@arr
are 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@arr
are 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 becauseuniq
is not applied):That is, the result has about 1,600 digits. What platform will you be running this on?