-
-
Save ara-ta3/3e3a97380a56f4fbb016f51e938c2c57 to your computer and use it in GitHub Desktop.
CTO Challenge 2016 2nd LV2
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
from typing import List, Dict | |
from functools import reduce | |
from collections import Counter | |
from menu import Menu | |
Coupon = int | |
class CouponSelector(): | |
def __init__(self, | |
limitation_of_coupons: Dict[Coupon, int], | |
coupons_available_for_pizza: List[Coupon], | |
lowest_amount_for_using_coupon: int | |
) -> None: | |
self.limitation_of_coupons = limitation_of_coupons | |
self.coupons_available_for_pizza = coupons_available_for_pizza | |
self.lowest_amount_for_using_coupon = lowest_amount_for_using_coupon | |
def select_optimum_combination_by_menus( | |
self, | |
menus: List[Menu], | |
coupons: List[Coupon]): | |
amount = reduce(lambda amount, m: amount + m.price, menus, 0) | |
available_coupons = _filter_limited_coupons( | |
coupons, | |
self.limitation_of_coupons | |
) | |
if not _pizza_exists(menus): | |
available_coupons = [c for c in available_coupons | |
if c not in self.coupons_available_for_pizza] | |
return self.select_optimum_combination(amount, available_coupons) | |
def select_optimum_combination(self, amount: int, coupons: List[Coupon]): | |
if amount <= self.lowest_amount_for_using_coupon: | |
return [] | |
sorted_coupons = sorted(coupons, reverse=True) | |
rest = amount | |
used_coupons = [] | |
for c in sorted_coupons: | |
if rest < c: | |
break | |
rest -= c | |
used_coupons.append(c) | |
return used_coupons | |
def _pizza_exists(menus: List[Menu]): | |
return any(m.is_pizza() for m in menus) | |
def _filter_limited_coupons( | |
coupons: List[Coupon], | |
coupon2limit: Dict[Coupon, int]): | |
counter = Counter(coupons) | |
for c, n in counter.items(): | |
counter[c] = min(coupon2limit[c], n) | |
return list(counter.elements()) |
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
from coupon_selector import CouponSelector | |
coupon_selector = CouponSelector({}, [], 1000) | |
def test_select_optimum_combination_case1(): | |
selected = coupon_selector.select_optimum_combination( | |
1000, | |
[500, 500, 200, 100, 100, 100] | |
) | |
assert selected == [] | |
def test_select_optimum_combination_case2(): | |
selected = coupon_selector.select_optimum_combination(1210, []) | |
assert selected == [] | |
def test_select_optimum_combination_case3(): | |
selected = coupon_selector.select_optimum_combination( | |
1210, | |
[500, 500, 200, 100, 100, 100] | |
) | |
assert selected == [500, 500, 200] | |
def test_select_optimum_combination_case4(): | |
selected = coupon_selector.select_optimum_combination( | |
1530, | |
[500, 500, 200, 100, 100, 100] | |
) | |
assert selected == [500, 500, 200, 100, 100, 100] | |
def test_discounted_in_order_when_coupons_are_not_sorted(): | |
selected = coupon_selector.select_optimum_combination( | |
1530, | |
[500, 200, 100, 500, 100, 100] | |
) | |
assert selected == [500, 500, 200, 100, 100, 100] |
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
from coupon_selector import CouponSelector | |
from menu import PizzaMenu, SideMenu | |
coupon_selector = CouponSelector( | |
{500: 2, 200: 2, 100: 3, 400: 1}, | |
[400], | |
1000 | |
) | |
def test_select_optimum_combination_by_menu_case1_on_lv2(): | |
menus = [PizzaMenu("ジェノベーゼ", "M", 1000)] | |
selected = coupon_selector.select_optimum_combination_by_menus( | |
menus, | |
[500, 200, 100, 400] | |
) | |
assert selected == [] | |
def test_select_optimum_combination_by_menu_case2_on_lv2(): | |
menus = [PizzaMenu("マルゲリータ", "M", 1200)] | |
selected = coupon_selector.select_optimum_combination_by_menus( | |
menus, | |
[] | |
) | |
assert selected == [] | |
def test_select_optimum_combination_by_menu_case3_on_lv2(): | |
menus = [ | |
SideMenu("ポテトフライ", 400), | |
SideMenu("ポテトフライ", 400), | |
SideMenu("シーザーサラダ", 600) | |
] | |
selected = coupon_selector.select_optimum_combination_by_menus( | |
menus, | |
[500, 500, 200, 100, 100, 400] | |
) | |
assert selected == [500, 500, 200, 100, 100] | |
def test_select_optimum_combination_by_menu_case4_on_lv2(): | |
menus = [PizzaMenu("ジェノベーゼ", "L", 1400)] | |
selected = coupon_selector.select_optimum_combination_by_menus( | |
menus, | |
[500, 500, 200, 100, 100, 400] | |
) | |
assert selected == [500, 500, 400] | |
def test_select_optimum_combination_by_menu_case5_on_lv2(): | |
menus = [PizzaMenu("ジェノベーゼ", "M", 1000), PizzaMenu("マルゲリータ", "M", 1200)] | |
selected = coupon_selector.select_optimum_combination_by_menus( | |
menus, | |
[500, 500, 500, 200, 200, 200, 100, 100, 100, 100, 400, 400] | |
) | |
assert selected == [500, 500, 400, 200, 200, 100, 100, 100] |
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
pip=bin/pip | |
python=bin/python | |
flake8=bin/flake8 | |
pytest=bin/pytest | |
run: $(python) | |
$< main.py -c $(cs) -m $(ms) | |
test: $(pytest) | |
$< -v ./lv1_test.py ./lv2_test.py | |
install: $(pip) | |
$< install -r requirements.txt | |
$(pytest): $(pip) | |
$(MAKE) install | |
$(python): | |
virtualenv . -p python3 | |
$(pip): | |
virtualenv . -p python3 | |
clean: | |
rm -rf ./bin | |
rm -rf ./lib | |
rm -rf ./include |
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
pytest | |
flake8 | |
mypy-lang |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment