Под катом опенсорс.
#! /usr/bin/env python """ Dumbell tabulate Take a set of dumbell discs, limit of single arrangement and print all arrangements sorted by sum """ def get_inputs(): """ @return: dictionary with elements "discs" (array of floats) and "limit" (integer) """ return {"discs": [5, 2.5, 2, 1.5, 1.25], "limit": 4} def build_discs_key(discs): """ Build a string representation of given discs set @param discs: list of floats @return: string representing those elements """ # "[__{}__]".format(d) return ' '.join([str(d) for d in sorted(discs, reverse=True)]) def subsets(elements, amount): """ Get all subsets of array elements with exactly "amount" items For amount == 1 - return list of elements For amount == N - take all combinations of N-1 + the rest """ if amount <= 1: return [[e] for e in elements] result = [] for e in elements: # build subset of "e" and combinations of the rest subset = elements[:] subset.remove(e) for s in subsets(subset, amount-1): result.append([e]+s) return result def generate_options(discs, limit): """ Generate possible options from inputs @param discs: list of disc weights @param limit: max amount of discs per option @return: dictionary of combinations and their weights combination is an ordered set of weights in string representation """ combinations = {} key = build_discs_key(discs) print("Discs set: {}".format(key)) print("Discs capacity: {}".format(limit)) for total in range(1, limit+1): # take all combinations of "total" discs from array for combination in subsets(discs, total): key = build_discs_key(combination) # skip existing combinations if key in combinations: continue combinations[key] = sum(combination) return combinations def show_result(options): result = [[options[k], k] for k in options.keys()] result.sort(key=lambda x: x[0]) for line in result: print("%4.2f %s" % (line[0]*4, line[1])) def main(): inputs = get_inputs() options = generate_options(inputs["discs"], inputs["limit"]) show_result(options) if __name__ == "__main__": main()