It looks like you are calculating every single possible combination, and then keeping only the combinations that satisfy your sum condition. The combination pool it is searching through grows at a rate 2^(n-1) which you can see by commenting out the condition part:
import itertools
import time
startTime = time.time()
val = 21
r = range(val)[1:]
res = []
for i in range(len(r)+1):
res += [list(x) for x in itertools.combinations(r, i)]# if sum(list(x)) == val]
#print("Solution : %s " % res)
print("Combinations : %s" % len(res))
print(time.time() - startTime, 'seconds')
Try this:
def a(lst, target, with_replacement=False):
def _a(idx, l, r, t, w):
if t == sum(l): r.append(l)
elif t < sum(l): return
for u in range(idx, len(lst)):
_a(u if w else (u + 1), l + [lst[u]], r, t, w)
return r
return _a(0, [], [], target, with_replacement)
val = 50
s = range(1, val)
solutions = a(s, val)
print(solutions)
print(len(solutions))
which is modified from code by thefourtheye:
Finding Combinations to the provided Sum value
timing it:
original code:
val = 24, t = 6.5917372703552253 seconds
val = 25, t = 13.705767631530762 seconds
val = 26, t = 27.934977531433105 seconds
val = 50, t = 459889248.39282094 seconds
above method:
val = 24, t = 0.0084612369537353 seconds
val = 25, t = 0.0069310665130615 seconds
val = 26, t = 0.0085859298706054 seconds
val = 50, t = 0.4947729110717773 seconds