-2

EDIT:

Hello all, I've edited my code to the below. When I enter "subset_sum(k, 47)" it correctly returns "sum([22, 25])=47; sum([25, 22])=47; sum([-11, 58])=47; sum([58, -11])=47.

When I enter "subset_sum(y, 47) it returns nothing (when it should return the same as "subset_sum(k, 47)" since k is included in the concatenated list of y).

Below is my current code:

def subset_sum(numbers, target, partial=[]):
    s = sum(partial)
    if len(numbers) == 0:
        return
    elif s == target:
        print("sum({})={}".format(partial, target))
        return
    else:
        for i in range(len(numbers)):
            n = numbers[i]
            remaining = numbers[:i] + numbers[i+1:]
            subset_sum(remaining, target, partial + [n])

s = [2, 4]
k = [22, 25, -11, 13, 58]
x = [100, 101, 23]
v = [77, 88, 99]

y = s+k+x+v

if __name__ == "__main__":
    subset_sum(y, 47)

Thanks all!

KevinA626
  • 3
  • 3
  • What is `y = int[s+k+x+v]` supposed to be doing? Please also include the complete traceback and try to minimize the code necessary to reproduce the issue (see [mcve]). Also the indentation is off in your function. – MSeifert Oct 25 '17 at 12:55
  • Concatenating the four lists - when I try to enter all numbers into one list, it seems that there are too many numbers and doesn't let me. – KevinA626 Oct 25 '17 at 12:55
  • If you want to concatenate them just use `y = s+k+x+v` without the `int`. I was wondering what you expected of the `int` in that line. – MSeifert Oct 25 '17 at 12:57
  • Your current code doesn't throw the exception you mentioned in the question title. – MSeifert Oct 25 '17 at 13:01
  • Your code still hasn't changed as @MSeifert suggested: you're creating a list of list by y = [s+k+x+v]; simply feed the sum into y: y = s+k+x+v. And then, y[:i] will yield the list element you want. – skrubber Oct 25 '17 at 13:14
  • I've edited the code. Any suggestions? Thanks again! – KevinA626 Oct 25 '17 at 13:55

1 Answers1

0

From what I can tell, the code block you've provided appears to be a modification of an algorithm from an answer to a previous question which asked how to generate all combinations of a list that sum to a given number. However, your modification appears to generate permutations as opposed to combinations.

If you want the permutations, consider that those permutations which are solutions to the sum(numbers) == target condition are also permutations of the elements of those combinations which are solutions to the same. So what you may want to do instead is find the combinations which satisfy the relation and take the permutations of the elements of those solutions to get all permutations of the list which are solutions of the condition. i.e.,

from itertools import combinations, permutations

def subset_sum(numbers, target):

    for length in range(len(numbers)):

       for combination in combinations(numbers, length):

            if sum(combination) == target: 

                for permutation in permutations(combination, len(combination)):

                    print("sum({}) = {}".format(list(permutation), target))

s = [2, 4]
k = [22, 25, -11, 13, 58]
x = [100, 101, 23]
v = [77, 88, 99]

y = s + k + x + v

if __name__ == "__main__":

    subset_sum(y, 47)

Note that calling subset_sum(k, 47) still prints the same solutions:

sum([22, 25]) = 47
sum([25, 22]) = 47
sum([-11, 58]) = 47
sum([58, -11]) = 47

And calling subset_sum(y, 47) prints:

sum([22, 25]) = 47
sum([25, 22]) = 47
sum([-11, 58]) = 47
sum([58, -11]) = 47
sum([2, 22, 23]) = 47
sum([2, 23, 22]) = 47
sum([22, 2, 23]) = 47
sum([22, 23, 2]) = 47
sum([23, 2, 22]) = 47
sum([23, 22, 2]) = 47
sum([22, -11, 13, 23]) = 47
sum([22, -11, 23, 13]) = 47
sum([22, 13, -11, 23]) = 47
sum([22, 13, 23, -11]) = 47
sum([22, 23, -11, 13]) = 47
sum([22, 23, 13, -11]) = 47
sum([-11, 22, 13, 23]) = 47
sum([-11, 22, 23, 13]) = 47
sum([-11, 13, 22, 23]) = 47
sum([-11, 13, 23, 22]) = 47
sum([-11, 23, 22, 13]) = 47
sum([-11, 23, 13, 22]) = 47
sum([13, 22, -11, 23]) = 47
sum([13, 22, 23, -11]) = 47
sum([13, -11, 22, 23]) = 47
sum([13, -11, 23, 22]) = 47
sum([13, 23, 22, -11]) = 47
sum([13, 23, -11, 22]) = 47
sum([23, 22, -11, 13]) = 47
sum([23, 22, 13, -11]) = 47
sum([23, -11, 22, 13]) = 47
sum([23, -11, 13, 22]) = 47
sum([23, 13, 22, -11]) = 47
sum([23, 13, -11, 22]) = 47

If, however, you only want the combinations, the code is simply:

from itertools import combinations, permutations

def subset_sum(numbers, target):

    for length in range(len(numbers)):

       for combination in combinations(numbers, length):

            if sum(combination) == target:

                print("sum({}) = {}".format(list(combination), target))

s = [2, 4]
k = [22, 25, -11, 13, 58]
x = [100, 101, 23]
v = [77, 88, 99]

y = s + k + x + v

if __name__ == "__main__":

    subset_sum(y, 47)

Where calling subset_sum(k, 47) prints:

sum([22, 25]) = 47
sum([-11, 58]) = 47

And calling subset_sum(y, 47) prints:

sum([22, 25]) = 47
sum([-11, 58]) = 47
sum([2, 22, 23]) = 47
sum([22, -11, 13, 23]) = 47
Erick Shepherd
  • 1,403
  • 10
  • 19
  • 1
    Erick, this is great! Thanks a million. Don't mean to be a pest, but is there anyway to get the script to return a combination once without any duplicates? It's providing the same combination just with the numbers rearranged. If not, no worries. Thanks again! – KevinA626 Oct 25 '17 at 17:46
  • @KevinA626 I just added an explanation for *just* combinations at the bottom per your request. – Erick Shepherd Oct 25 '17 at 17:54
  • any chance you can get the script to return "Complete" once all combinations have been checked? Thanks again for the help! – KevinA626 Oct 26 '17 at 16:45
  • @KevinA626 Return "complete" as a string, or just print "complete" within the function as it finishes? – Erick Shepherd Oct 26 '17 at 22:45