def mix_and_match(limit, items, verbose = False):
# filter items
items = [(size, name) for size, name in items if size <= limit]
# sort them by size
items.sort(lambda (xsize, xname), (ysize, yname): cmp(xsize, ysize))
# initialize variables
added_collections = dict([(set([name]), size) for size, name in items])
collections = added_collections
while True:
if verbose:
sys.stderr.write("%d\n" % len(collections))
# find unique combinations of the recent collections
new_collections = {}
for names1, size1 in added_collections.iteritems():
for size2, name2 in items:
size3 = size1 + size2
if size3 > limit:
# we can break here as all collections that follow are
# bigger in size due to the sorting above
break
if name2 in names1:
continue
names3 = names1.union(set([name2]))
if names3 in new_collections:
continue
new_collections[names3] = size3
if len(new_collections) == 0:
break
collections.update(new_collections)
added_collections = new_collections
return [(size, names) for names, size in collections.iteritems()]
评论列表
文章目录