Created
August 4, 2014 15:37
-
-
Save zeayes/019f9cc5c3ac6397bfff to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
MAX_TAX = 500 | |
MAX_PRICE = 1000 | |
class Item(object): | |
"""商品类""" | |
def __init__(self, price, tax_rate, category): | |
""" | |
:price: 商品单价 | |
:tax_rate: 商品税率 | |
:category: 商品类别 | |
""" | |
self.price = price | |
self.tax_rate = tax_rate | |
self.category = category | |
@property | |
def tax(self): | |
""" | |
:returns: 单件商品的关税 | |
""" | |
return self.price * self.tax_rate | |
def __repr__(self): | |
return 'price: %s tax: %s category: %s' % (self.price, self.tax, self.category) | |
def tax_sum(items): | |
return sum([item.tax for item in items]) | |
def amount_sum(items): | |
return sum([item.price for item in items]) | |
def pack_sorted_items(items, packages): | |
""" | |
打包商品 | |
""" | |
count = len(items) | |
if count == 0: | |
return | |
elif count == 1: | |
packages.append(items) | |
return | |
remain_items, suitable_items = get_suitable_items(items[-1], items[:-1]) | |
packages.append(suitable_items) | |
return pack_sorted_items(remain_items, packages) | |
def get_suitable_items(item, items): | |
""" | |
从商品库items里面选取符合条件且不多于2个的商品 | |
返回剩下的商品库和打包的商品 | |
""" | |
suitable_items = [item] | |
if item.category == 'SHOES': | |
items, suitable_items = pick_item(items, suitable_items, 'HANDBAG') | |
items, suitable_items = pick_item(items, suitable_items, 'HANDBAG') | |
return items, suitable_items | |
elif item.category == 'HANDBAG': | |
items, suitable_items = pick_item(items, suitable_items, 'SHOES') | |
items, suitable_items = pick_item(items, suitable_items, 'SHOES') | |
return items, suitable_items | |
suitable_items.append(items[0]) | |
first_picked_item = items[0] | |
items.remove(items[0]) | |
# 通过第一个物品的类别选取第二个物品 | |
if first_picked_item.category == 'SHOES': | |
items, suitable_items = pick_item(items, suitable_items, 'HANDBAG') | |
elif first_picked_item.category == 'HANDBAG': | |
items, suitable_items = pick_item(items, suitable_items, 'SHOES') | |
else: | |
items, suitable_items = pick_item(items, suitable_items) | |
return items, suitable_items | |
def pick_item(items, suitable_items, category=None): | |
""" | |
选取第一个符合条件的商品 | |
""" | |
first_picked_item = items[0] if items and not category else None | |
if category: | |
for item in items: | |
if item.category != category: | |
first_picked_item = item | |
break | |
# 判断是否满足条件条件 | |
if not first_picked_item \ | |
or amount_sum(suitable_items) + first_picked_item.price >= MAX_PRICE \ | |
or tax_sum(suitable_items) + first_picked_item.tax >= MAX_TAX: | |
return items, suitable_items | |
# 把符合条件的商品放进包裹里面 | |
suitable_items.append(first_picked_item) | |
items.remove(first_picked_item) | |
return items, suitable_items | |
def pack(items): | |
packages = [] | |
sorted_items = sorted(items, key=lambda x: x.price) | |
for item in sorted_items: | |
# 单价或者关税大于指定金额的商品单独打包 | |
if item.price >= MAX_PRICE or item.tax >= MAX_TAX: | |
packages.append([item]) | |
sorted_items.remove(item) | |
# 对剩下的商品进行打包 | |
pack_sorted_items(sorted_items, packages) | |
return packages |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment