Skip to content
Advertisement

recursive implementation of sum to target Python

I have the following method that, given a target integer, generates all ways to create that integer from an ordered row of integers, subject to the condition that the column index (starting from one) multiplied by the number sums to the target for each row.

Below is some code that achieves this.

target = 7
for x in range(math.floor(target/4)+1):
    for f in range(math.floor((target-4)/3)+1):
        for t in range(math.floor((target-4*x-3*f)/2)+1):
            s = target - 2*t - 3*f - 4*x
            print(s,t,f,x)

7 0 0 0
5 1 0 0
3 2 0 0
1 3 0 0
4 0 1 0
2 1 1 0
0 2 1 0
3 0 0 1
1 1 0 1
0 0 1 1

Notice that all rows sum to target=7, i.e. take the bottom row 0*1 + 0*2 + 1*3 + 1*4=7.

In the general case, I do not know the number of columns that I require. For instance, I might simply have

target = 7
for t in range(math.floor(target/2)+1):
    s = target - 2*t
    print(s,t)

or indeed, many more for loops.

How can I generalise this, most likely based on a recursive solution, so that the number of columns is a parameter?

Advertisement

Answer

Here is a recursive solution. You just run through the options for the last column, then fetch the combinations for whatever’s leftover using the remaining columns.

def gencombos( target, column ):
    if column == 1:
        yield [target]
    else:
        for i in range( 0, target//column+1 ):
            for row in gencombos( target-i*column, column-1 ):
                yield row+[i]

for row in gencombos( 7, 4 ):
    print(row)

Output:

[7, 0, 0, 0]
[5, 1, 0, 0]
[3, 2, 0, 0]
[1, 3, 0, 0]
[4, 0, 1, 0]
[2, 1, 1, 0]
[0, 2, 1, 0]
[1, 0, 2, 0]
[3, 0, 0, 1]
[1, 1, 0, 1]
[0, 0, 1, 1]

You can change it the call to (7,6) to see the difference.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement