Home > Blockchain >  What is the most efficient way to choose from a list of variables and generate a number combination
What is the most efficient way to choose from a list of variables and generate a number combination

Time:11-02

I have a set of variables each containing an array of chosen integers:

var_1 = [0.5, 1, 2]
var_2 = [0.5, 1, 4, 7.5]
var_3 = [1, 1.5, 3.5, 4, 5.5, 10]

I would like to choose each number from each of the stated variables above and add them together until the first combination of those variables falls within a specified win range such as:

winning_range = [15-20]

So the above winning_range would be the first combination that falls between integers 15-20

I would like to print the winning combination as a dictionary with each combination piece along with a dictionary key showing the value of the numbers added up:

{var_1 = 2, var_2= 7.5, var_3= 10, total= 19.5}

What would be the most efficient way to obtain this through python?

CodePudding user response:

Maybe not the most efficient, but pretty human readable

var_1 = [0.5, 1, 2]
var_2 = [0.5, 1, 4, 7.5]
var_3 = [1, 1.5, 3.5, 4, 5.5, 10]

winning_range = [15, 20] # Converting to a list for [min, max]
result = {}

for v1 in var_1:
    for v2 in var_2:
        for v3 in var_3:
            if v1 v2 v3 in range(winning_range[0], winning_range[1]):
                result = {"var_1": v1, "var_2": v2, "var_3": v3}
                
print(result)
# Output
# {'var_1': 2, 'var_2': 7.5, 'var_3': 5.5}

I should add you specified the first combination, so this solution is literally attempting them sequentially.

CodePudding user response:

You can use a recursive generator function:

r = [15, 20]
var_1 = [0.5, 1, 2]
var_2 = [0.5, 1, 4, 7.5]
var_3 = [1, 1.5, 3.5, 4, 5.5, 10]
def combos(d, c = [], s = 0):
  if not d and r[0] <= s and r[-1] >= s:
     yield (c, s)
  elif d:
     for i in filter(lambda x:r[-1] >= x s, d[0]):
        yield from combos(d[1:], c=c [i], s=s i)

print(list(combos([var_1, var_2, var_3])))

Output:

[([0.5, 7.5, 10], 18.0), ([1, 4, 10], 15), ([1, 7.5, 10], 18.5), ([2, 4, 10], 16), ([2, 7.5, 5.5], 15.0), ([2, 7.5, 10], 19.5)]

Here, at each recursive call, potential values from a var list are only included if the running sum plus the value does not exceed the maximum threshold, thus minimizing the total number of recursive calls needed. While list(combos([var_1, var_2, var_3])) loads all the possibilities into memory, you can use next to grab only the first result:

vals, total = next(combos([var_1, var_2, var_3]))
  • Related