Warm tip: This article is reproduced from serverfault.com, please click

How make a especific combinations in python?

发布于 2020-11-28 12:12:44

I'm trying to make a specific combination so that it adds up to "4" by adding the following specs:

a+a+a+a+a+a+a+a = 0.5 per/unit  = (In total it sum:) 4
b+b+b+b = 1 per/unit  = (In total it sum:) 4
c+c = 2 per/unit  = (In total it sum:) 4

That way I want to know the result and print the combinations on the screen:

a+a+a+a+a+a+a+a = 4
a+a+a+a+a+a+b = 4
a+a+a+a+b+b = 4
a+a+b+b+b = 4
a+a+a+a+a+a+c = 4
a+a+b+c = 4
a+a+c+b = 4
b+a+a+a+a+a+a = 4
b+b+a+a+a+a = 4
b+b+b+a+a = 4
b+b+c = 4
b+c+a+a = 4
b+a+c = 4
b+c+a = 4
c+a+a+a+a = 4
c+b+a+a = 4
c+a+a+b = 4

My code:

from itertools import combinations
numbers=[2,4,8]
for c in combinations(numbers, 3):
    print(c)

Is there a way to do it that specific way? Thanks very much for readme.

Questioner
Ulises Antonio Chávez
Viewed
0
Marc 2020-11-28 22:54:36

I'll try to answer you question in a didactically fashion without supplying the full code (as you requested in the comment above).

  1. combinatory approach

The straight forward solution would be to just look at possible combinations of the numbers array for different lengths. Looping over the lengths as well as over the combinations you can check whether the sum over these elements gives your solution.

You should look at the function itertools.combinations_with_replacement as it allows multiple occurrances of each element.

from itertools import combinations_with_replacement

numbers=[2,4,8]
for length in [3]:
   for c in combinations_with_replacement(numbers, length):
      print(c, f"sum {sum(c)}")

> (2, 2, 2) sum 6
> (2, 2, 4) sum 8
> (2, 2, 8) sum 12
> (2, 4, 4) sum 10
> (2, 4, 8) sum 14
> (2, 8, 8) sum 18
> (4, 4, 4) sum 12
> (4, 4, 8) sum 16
> (4, 8, 8) sum 20
> (8, 8, 8) sum 24

You would have to specify the length-array accordingly and add an if-clause for printing.

  1. functional approach:

Assume the function you are looking for is defined as def calcComb(sum,numbers): ... which returns a string of combinations you have tried.

The typical functional solution to this problem is recursively calling an inner function rec(sumRest,numRest,textComb) that keeps track of the sum your building up as well as the combination (here in string format) you are testing. The skeletal structure would be something like:

def rec(sumRest,numRest,textComb):
 if  ... :  return ... 
 elif ... : return ...
 else :
    newText = ...
    return rec(sumRest-numRest[0],numRest,textComb+newText) 
          + rec(sumRest,numRest[1:],textComb) 

edit :

The above approaches are straight-forward implementations of the problem and are not optimized with respect to performance. If your problem scales up you might be interested to save the state of previous calculation steps (dynamic approach) or cache intermediate results in a dicationary (memoization).