Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import itertools
- import string
- weight_sizes = [2,3,4] # the variables to use
- weight_needed = 15
- max_weights_per_sol = 7
- def main():
- print_solutions()
- def print_solutions():
- weight_sizes.sort()
- letters = assign_variables()
- solutions = get_solutions()
- print_var_letters(letters)
- for sol in solutions:
- print_solution(sol, letters)
- def assign_variables():
- wvars = {}
- for i in range(len(weight_sizes)):
- wvars[weight_sizes[i]] = string.ascii_lowercase[i]
- return wvars
- def print_solution(sol, letters):
- out = ""
- for weight in set(sol):
- out += str(sol.count(weight))
- out += letters[weight]
- out += " + "
- print(out[:-3])
- def print_var_letters(letters):
- print("Let ", end="")
- for size, letter in letters.items():
- print(letter + " = " + str(size) + ", ", end="")
- print()
- def get_solutions():
- solutions = []
- n = max_weights_per_sol
- for n in range(1,max_weights_per_sol+1):
- solutions_for_n = get_unique_solutions(n)
- solutions += (solutions_for_n)
- # solutions = get_unique_solutions(n)
- return solutions
- def get_unique_solutions(n):
- sorted_sols = sort_with_sublists(calculate_solutions(n))
- unique_sols = list(x for x,_ in
- itertools.groupby(sorted_sols))
- return unique_sols
- def sort_with_sublists(lst):
- for sub in lst:
- sub = sub.sort()
- lst.sort()
- return lst
- def calculate_solutions(n):
- permutations = multichoose(n, weight_sizes)
- permutations = remove_invalid_sums(permutations)
- # print(list(permutations))
- return containsonly(weight_sizes, permutations)
- def remove_invalid_sums(lsts):
- out = []
- # Cannot sum to weight_needed if its smallest possible value is repeated
- # more times than the largest possible quotient
- maximum_lenth = weight_needed/min(weight_sizes)
- for l in lsts:
- if len(l) > maximum_lenth:
- continue
- if sum(l) == weight_needed:
- out.append(l)
- return out
- def containsonly(nums, lst):
- to_remove = []
- for combo in lst:
- for num in combo:
- if num not in nums:
- to_remove.append(combo)
- for combo in to_remove:
- if combo in lst:
- lst.remove(combo)
- return lst
- # https://github.com/ekg/multichoose/blob/master/multichoose.py
- # https://stackoverflow.com/questions/37711817/generate-all-possible-outcomes-of-k-balls-in-n-bins-sum-of-multinomial-catego
- def multichoose(k, objects):
- """n multichoose k multisets from the list of objects. n is the size of
- the objects."""
- j,j_1,q = k,k,k # init here for scoping
- r = len(objects) - 1
- a = [0 for i in range(k)] # initial multiset indexes
- while True:
- yield [objects[a[i]] for i in range(0,k)] # emit result
- j = k - 1
- while j >= 0 and a[j] == r: j -= 1
- if j < 0: break # check for end condition
- j_1 = j
- while j_1 <= k - 1:
- a[j_1] = a[j_1] + 1 # increment
- q = j_1
- while q < k - 1:
- a[q+1] = a[q] # shift left
- q += 1
- q += 1
- j_1 = q
- main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement