0

I'm trying to get all possible combinations that equal a target sum. The script that I have does this perfectly well, however I need the output to show the original index number. The script I have outputs the correct number combinations, but not the correct index.

Example of correct output:

input=([1, 2, 3, 4], target_sum=6) output=[1,3], [0,1,2]

The code I have is the following (source):

numbers = [1,2,3,4,5]
target = 6    

def calc_combo(input_number, target_sum, partial=[]):
    total = sum(partial)
    idx = []
    index = [[num,indices] for indices,num in enumerate(partial)]

    if total == target_sum:    
        for i in index:
            idx.append(i)
        print(str(idx) + " = " + str(target_sum))     

    if total >= target_sum:
        return

    for i in range(len(input_number)):
        n = input_number[i]
        remaining = input_number[i+1:]
        calc_combo(remaining, target_sum, partial + [n])

calc_combo(numbers, target)

Which gives the following output:

[[1, 0], [2, 1], [3, 2]] = 6
[[1, 0], [5, 1]] = 6
[[2, 0], [4, 1]] = 6

Any help is greatly appreciated!

Sean H.
  • 1
  • 2

1 Answers1

0

You can use list.index(elem) to get the index of an element in a list

In your code you may replace the line

index = [[num,indices] for indices,num in enumerate(partial)] with

index = [[num,input_number.index(num)] for num in partial].

Otherwise, you can use the following code, which considers all combinations and doesn't use the function index and returns a list of (nums, indexes) instead of printing a list of lists of (num, index):

def combo(options, target):
    ret = []
    for level in range(len(options)):
        for i,c in enumerate(options):
            for j,g in enumerate(options[i+1:]):
                if i+1+j+level <= len(options):
                    combo = [c,*options[i+1+j:i+1+j+level]]
                    if sum(combo) == target:
                        index = [i,*list(range(i+1+j,i+1+j+level))]
                        ret.append((combo, index))
                if level == 0:
                    break
    return ret

The expected output for Python 3:

>>>combo(list(x*2**-2 for x in range(-4,5,1)), 2)
[([0.25, 0.75, 1.0], [5, 7, 8]),
 ([-0.25, 0.5, 0.75, 1.0], [3, 6, 7, 8]),
 ([-0.5, 0.25, 0.5, 0.75, 1.0], [2, 5, 6, 7, 8]),
 ([-0.5, 0.0, 0.25, 0.5, 0.75, 1.0], [2, 4, 5, 6, 7, 8])]
Matteo T.
  • 1,278
  • 11
  • 13
  • Thanks for your response, I appreciate it. This is my first time delving into this subject. I tried replacing the one-liner you gave me however it came up with errors that X wasn't in list. Would there be a way to compare the output entries with the original numbers list? Then return the index of the original list? – Sean H. Jan 20 '18 at 20:19