All possible combinations in a list of numbers AND adding a value to each combination result to reach a target value

Please help.

I found a couple of code examples that partially do what I need (see below). Can you please help me modify either code to do what I need?

I need to find all the combinations in a list of numbers and to each combination to substract (or add, multiply, or divide) a value AND then to find which result sums to a specific value.

For example:

  1. Here is a number list: 10, 12, 3, 4, 8
  2. And here is the value I want to substract from each combination: 5
  3. And here is the final target value (product) to find (only the combinations that give this result should be printed): 7

So the computation should be (I’m giving only the general idea since the actual list could be potentially longer):

10 - 5 = 5
10 + 12 - 5 = 17
10 + 12 + 3 - 5 = 20
10 + 12 + 3 + 4 - 5 = 24
10 + 12 + 3 + 4 + 8 - 5 = 32
12 - 5 = 7
12 + 3 - 5 = 10
12 + 3 + 4 - 5 = 14
12 + 3 + 4 + 8 - 5 = 22
3 - 5 = -2
3 + 4 - 5 = 2
3 + 4 + 8 - 5 = 10
4 - 5 = -1
4 + 8 - 5 = 7

And the only combinations that should “print” are:

12 - 5 = 7
4 + 8 - 5 = 7

Here are the two sample codes that I found and partially do what I need:

def subset_sum(numbers, target, partial=[]):
    s = sum(partial)

    # check if the partial sum is equals to target
    if s == target:
        print("sum(%s)=%s" % (partial, target))
    if s >= target:
        return  # if we reach the number why bother to continue

    for i in range(len(numbers)):
        n = numbers[i]
        remaining = numbers[i + 1:]
        subset_sum(remaining, target, partial + [n])


if __name__ == "__main__":
    subset_sum([10, 12, 3, 4, 8], 7)

and the second one:

class Solution(object):
   def combinationSum(self, candidates, target):
      result = []
      unique={}
      candidates = list(set(candidates))
      self.solve(candidates,target,result,unique)
      return result
   def solve(self,candidates,target,result,unique,i = 0,current=[]):
      if target == 0:
         temp = [i for i in current]
         temp1 = temp
         temp.sort()
         temp = tuple(temp)
         if temp not in unique:
            unique[temp] = 1
            result.append(temp1)
         return
      if target <0:
         return
      for x in range(i,len(candidates)):
         current.append(candidates[x])
         self.solve(candidates,target-candidates[x],result,unique,i,current)
         current.pop(len(current)-1)
ob1 = Solution()
print(*ob1.combinationSum([10, 12, 3, 4, 8],7), sep='\n')

In advance, thank you for any help provided. I’m new to Python as you can tell.

Try this code:

from itertools import combinations
numbers = (2, 3, 4, 5)
for count in range(1, 4):
    for t in combinations(numbers, count):
        print(t, sum(t))

Does that help solve your problem?

Beware though, if you have (say) ten numbers in the list, it will have
to loop a total of 1022 times, which is not many for the computer. But
if you have, say, a hundred numbers, the total number of loops will be
astronomical, and the computer may run for hours or days.

(You can halt the calculation by typing Ctrl-C at any time.)

Steven,

Unfortunately, the solution you suggested does not do what I need. Your solution prints all combinations found. I do not need that. I only need it to print those combinations that “sum” to a specific value BUT only after substracting a fixed value from all the combinations.

If using one of the codes I provided (after modifying it to substract a fix value, in this case “7”), the PRINT command should only show in the console these two results:

(12) - 5 = 7
(4 + 8) - 5 = 7

Or perhaps this other way:
(12) - 5 = 7
(4, 8) - 5 = 7

Any one knows how can I modify the existing code to add the subtraction of say “7” from the combinations found and then evaluate those combination to see which ones give the result of 7?

Thank you.

Note that finding all the sums that work after subtracting a number is exactly the same as finding all the sums that reach a particular target + that number. In other words, if you want to find everything that sums to 7 after subtracting 5, you can find everything that sums to 12.

Then print that combo and tack a “- 5 = 7” onto the end.

BowlOfRed, thanks.

But I am new at Python and I am not able to make it work. Can you please provide the code?

Also:

4 - 5 = -1, 8 - 5 = 3 then -1 - 3 = 2 is way different than 4+8-5 = 7 and I’m looking for this last way of doing things.

Thank you.

Hi Luis,

You are correct, I have not done your homework for you, I have given you
the tools you need to do your homework.

(I use “homework” here figuratively, not literally. Whether this is an
assignment you have been set by school, or work, or something you are
working on yourself, doesn’t really matter.)

You now have all the tools you need:

  • the combinations() function that works out each combination in turn;

  • a for-loop to check each combination, one at a time;

  • the sum() function that sums a list of numbers;

  • I think that you already know how to subtract 5;

  • I think that you already know how to test if a value is equal to 7;

  • and you know how to print.

So you should be able to put all the pieces together:

  • Use a for-loop and combinations to make each combo.

  • Use sum() and subtraction to get the value you want.

  • Use == and if to decide if the combo should be printed.

  • And use print() to actually print it.

As a beginner, you will learn a thousand times more by doing the work
yourself than if we just handed you a solution. If you want to learn to
cook, you actually have to go into the kitchen and prepare ingredients
and cook it. You won’t learn to cook by getting somebody else to do the
work. Same with programming.

At least make an effort to put the pieces together. If it works, great!
If it doesn’t, show us what you tried, and we’ll help you understand
what you did wrong and how to fix it.

A thought comes to mind that maybe you don’t actually know how to test
for equal values, or how to use if.

value = 24
if value == 9:
    print(value)

x = 17
if x == 17:
    print("x has value 17")

If you already knew this, apologies for wasting your time.

Steven,

You are correct, I do not know how to test for values in Python. Again, I am absolutely new to Python.

However, the code you posted originally does what I need - after typing in the subtraction:

from itertools import combinations
numbers = (10, 12, 3, 4, 8)
for count in range(1, 6):
    for t in combinations(numbers, count):
        print(t, sum(t)-5)

The -5 at the end of he print line does the trick (as you hinted).

It gives the following results, of which the 2nd and 15th rows (in bold) are the values I am looking for, and the only ones I would like to be shown:

(10,) 5
(12,) 7 <----------------
(3,) -2
(4,) -1
(8,) 3
(10, 12) 17
(10, 3) 8
(10, 4) 9
(10, 8) 13
(12, 3) 10
(12, 4) 11
(12, 8) 15
(3, 4) 2
(3, 8) 6
(4, 8) 7 <----------------
(10, 12, 3) 20
(10, 12, 4) 21
(10, 12, 8) 25
(10, 3, 4) 12
(10, 3, 8) 16
(10, 4, 8) 17
(12, 3, 4) 14
(12, 3, 8) 18
(12, 4, 8) 19
(3, 4, 8) 10
(10, 12, 3, 4) 24
(10, 12, 3, 8) 28
(10, 12, 4, 8) 29
(10, 3, 4, 8) 20
(12, 3, 4, 8) 22
(10, 12, 3, 4, 8) 32

HOWEVER, being that I know very little of Python, I do not know how to make your code to only show those two rows, those two combinations. I just watched some tutorials but they give examples that don’t help (using letters or “hello world” which do not work the same as when using numbers). I’ll keep trying…

Anyhow, thank you for the code you provided. It does what I need, although I would love if it would only show the target combinations instead of me having to visually find them.

And no, Sir, you are not wasting my time at all.

Have a blessed day.

Hi Luis,

Good to see you making an attempt to write some of the code yourself! We
were all beginners once, we all needed to learn.

Let me start by renaming one of the variables to a name which is more
useful. Variables should give the reader a hint of what they are. I’ll
also add some comments.

from itertools import combinations
numbers = (10, 12, 3, 4, 8)  # These can be any numbers you like.
for count in range(1, len(numbers)+1):
    for combo in combinations(numbers, count):
        print(combo, sum(combo)-5)

So far, nothing much has changed. I changed the meaningless variable
name “t” to “combo”, added a comment, and changed the mysterious number
6 to len(numbers)+1. Can you work out that that does?

You should run that, and check that it does what you expect it does.

Now let’s extract out the sum into a variable.

from itertools import combinations
numbers = (10, 12, 3, 4, 8)  # These can be any numbers you like.
for count in range(1, len(numbers)+1):
    for combo in combinations(numbers, count):
        value = sum(combo)-5
        print(combo, value)
        if value == 7:
            print("value equals 7")

If you run this code, you will see that it almost does what you want.
It still prints every combo, but now if the sum less 5 equals 7, it
also prints a message.

Can you see how to change that code to only print the combo if the value
is 7? Experiment! See if you can work out what changes you need.

Hint: you need to delete one line, and move one other line into its
place. You may need to adjust the indentation as well.

Steven,

This is beautiful.

Anything else I would say will just ruin the wow moment.

I will experiment tomorrow and report back, although I may just skip going to bed altogether. This is so captivating.

You are gifted sir.

Steven,

I couldn’t resist and I had to figure it out now:

from itertools import combinations
numbers = (10, 12, 3, 4, 8)  # These can be any numbers you like.
for count in range(1, len(numbers)+1):
    for combo in combinations(numbers, count):
        value = sum(combo)-5
        if value == 7:
            print(combo, "value equals", value)

Which gives:

(12,) value equals 7
(4, 8) value equals 7

And that’s exactly what I need. Awesome. Godly.

Thank you.

p.s. The mysterious number 6 was simply setting the depth of the combinations, in other words, how many numbers from the list to combine to find the target value. However, that number 6 had to be manually typed for a tentative depth. With the new code you put in, the calculations go as far as needed automatically.