from math import factorial
from itertools import combinations
from functools import partial
def binomial_coefficient(elements, extraction):
return factorial(elements)/(factorial(extraction)*factorial(elements-extraction))
def ℘(elements):
powerset=[]
for item in range(0,len(elements)+1):
for subset in list(combinations(elements,item)):
powerset.append(subset)
return powerset
def negate(exponent):
return (-1)**exponent
def combinatorial_subroutine(elements,extraction,outer_item,multiplicities):
if elements+extraction-outer_item-sum(multiplicities)>0:
return binomial_coefficient(elements-1+extraction-outer_item-sum(multiplicities),elements-1)
else:
return 0
def ΣΣ(inner_iterable,outer_iterable,inner_function,outer_function):
inner_sum=outer_sum=0
for outer_item in outer_iterable:
for inner_item in inner_iterable:
inner_sum+=inner_function(outer_item,inner_item)
outer_sum+=outer_function(outer_item)*inner_sum
inner_sum=0
return outer_sum
def multiset_combinations(extraction,*multiplicities):
elements=len(multiplicities)
partial_combinatorial_subroutine=partial(combinatorial_subroutine,elements,extraction)
return ΣΣ(℘(multiplicities),list(range(elements+1)),partial_combinatorial_subroutine,negate)
print(multiset_combinations(7,1,1,2,2,2,8))
input()