简体   繁体   中英

Python set sequence of numbers to add or subtract for certain result

In this hypothetical scenario I have a sequence of numbers of known, but random length and I need to set each number in the sequence to add or subtract to reach a given output and show the process.

Is there a way to do this without reinventing the wheel, such as a module?

EDIT: More Info:

I have a sequence of numbers like: 5 4 3 2 1 and I need to set each number to add (+) or subtract (-) to get a result such as 7. The result in this case would be 5+4-3+2-1. It could be a sequence of any numbers as far as there is a possible result. If there are multiple correct answers just one of them will do.

Edit:

Let's assume that no step in the equation results in an answer larger than 1000.

The easiest approach is to just brute-force all possible combinations of plus and minus, and return the first one that has the correct sum. You can use itertools.product to do this.

import itertools

def find_correct_operators(seq, total):
    signs = [-1,1]
    for item_signs in itertools.product(*[signs]*len(seq)):
        seq_with_signs_applied = [item*sign for item, sign in zip(seq, item_signs)]
        sum(seq_with_signs_applied)
        if sum(seq_with_signs_applied) == total:
            return item_signs

a = [5,4,3,2,1]
b = 7
signs = find_correct_operators(a,b)
if signs is not None:
    print "{} = {}".format(" ".join("{}{}".format("-" if sign == -1 else "+", item) for sign, item in zip(signs, a)), b)
else:
    print "No solution found"

Result:

+5 -4 +3 +2 +1 = 7

The drawback to this is that it runs in O(2^N) time, so it's highly unsuitable for any sequence of numbers larger than, say, twenty items long. By that point, you're iterating through more than a million possible combinations.


Edit: if you have some limit L and no intermediary step in the equation may ever evaluate to larger than L or smaller than -L, then you can find the answer in O(N*L) time, which is a considerable improvement for smallish values of L.

seq = [5,4,-3,2,1]
goal = 7
limit = 1000
d = {0: []}
for item in seq:
    next_d ={}
    for intermediary_total, path in d.iteritems():
        for candidate in [-item, item]:
            next_total = intermediary_total + candidate
            if abs(next_total) <= limit:
                next_d[next_total] = path + [candidate]
    d = next_d

if goal in d:
    print d[goal]
else:
    print "no solution found"

Result:

[5, 4, -3, 2, -1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM