Skip to content

Instantly share code, notes, and snippets.

@lesha-co
Last active June 5, 2016 15:36
Show Gist options
  • Save lesha-co/4dfa0f2457de8a7a7129e0a04959695f to your computer and use it in GitHub Desktop.
Save lesha-co/4dfa0f2457de8a7a7129e0a04959695f to your computer and use it in GitHub Desktop.
Задача с двача
# 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