Last active
June 5, 2016 15:36
-
-
Save lesha-co/4dfa0f2457de8a7a7129e0a04959695f 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 | |
""" | |
Двач, у меня для тебя жизненная математическая задача: | |
В пиццерии проводится акция: | |
Закажи 2 пиццы и получи 3-ю в подарок, но третья пицца должна быть не дороже среднего арифметического цен 2 пицц. | |
Тебе нужно заказать 6 пицц, соответственно только за 4 заплатив. | |
Нужно подобрать наиболее выгодный вариант заказа. | |
Цены: 72, 78, 81, 91, 92, 110. | |
""" | |
# Охренеть, питон по умолчанию не делит целые числа как дробные | |
from __future__ import division | |
# все пиццы: | |
pizzas = [72, 78, 81, 91, 92, 110] | |
limit = len(pizzas) | |
# проверка, можно ли купить эти две пиццы и получить третью бесплатно | |
def valid(paid, free): | |
return free <= (paid[0] + paid[1]) / 2 | |
# проверка тройки пицц. Можно ли собрать из них комбинацию, которую можно купить согласно условиям | |
# возвращает самый дешевый вариант или False, если таких нет | |
def check_trio(trio): | |
# Все варианты разбиения тройки пицц на две платные, и бесплатную. | |
all_combos = [ | |
[(trio[0], trio[1]), trio[2]], | |
[(trio[0], trio[2]), trio[1]], | |
[(trio[1], trio[2]), trio[0]] | |
] | |
# находятся все подходящие варианты этой комбинации | |
all_valid = filter(lambda combo: valid(combo[0], combo[1]), all_combos) | |
if len(all_valid) != 0: | |
# берем самый дешевый вариант этой тройки | |
return find_cheapest_option(all_valid) | |
return False | |
# ищет все разбиения 6 пицц на две тройки | |
def find_groups(all_pizzas): | |
groups = [] | |
for i in range(0, limit-2): | |
for j in range(i+1, limit-1): | |
for k in range(j+1, limit): | |
group_a = [i, j, k] | |
group_b = filter(lambda v: v not in group_a, range(0, limit)) | |
group_a = map(lambda idx: all_pizzas[idx], group_a) | |
group_b = map(lambda idx: all_pizzas[idx], group_b) | |
groups.append((group_a, group_b)) | |
return groups | |
# берет все варианты одной тройки и находит самый дешевый | |
def find_cheapest_option(trios): | |
return reduce(lambda x, y: x if sum(x[0]) < sum(y[0]) else y, trios) | |
# берем группу из двух троек пицц и проверяет ее корректность. | |
# Возвращает сформированный заказ или False | |
def prep_order(groups): | |
trios = map(check_trio, groups) | |
if trios[0] and trios[1]: | |
return { | |
"paid_a": trios[0][0], | |
"free_a": trios[0][1], | |
"paid_b": trios[1][0], | |
"free_b": trios[1][1], | |
"sum": sum(trios[0][0]) + sum(trios[1][0]) | |
} | |
return False | |
# все возможные тройки пары троек пицц | |
all_groups = find_groups(pizzas) | |
# все возможные заказы | |
all_orders = map(prep_order, all_groups) | |
# убираем некорректные заказы | |
all_orders = filter(None, all_orders) | |
# находим самый дешевый заказ | |
the_order = reduce(lambda a, b: a if a['sum'] < b['sum'] else b, all_orders) | |
print """\ | |
Первый заказ: платим за %(paid_a)s, бесплатно берем за %(free_a)s | |
Второй заказ: платим за %(paid_b)s, бесплатно берем за %(free_b)s | |
Итого %(sum)s""" % the_order |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment