Created
January 14, 2016 12:43
-
-
Save lordhx/129d34859e019c3e1fbc to your computer and use it in GitHub Desktop.
This file contains hidden or 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
def call | |
@all_dishes = [] | |
# У нас есть требование чтобы одно блюдо встречалось не более трех раз в неделю | |
# Таким образом получается что нам нужно подобрать 3 рациона на пн, вт, ср | |
# а дальше мы просто повторим их же | |
variants = 3.times.map do | |
# недобор или перебор по конкретным материалам, изначально все в 0 | |
@diff = {} | |
# находим записи Mapping соответвующие предпочтительному количеству приемов пищи | |
# группируем по приемам пищи, так как подбор рациона основан на нормах на прием пищи | |
Mapping.where(ingestion_count: @user.ingestion_count).group_by(&:meal).map do |meal, array| | |
# начинаем поис лучшего варианта для конкретного приема пищи | |
# здесь нам нужно сделать еще одну группировку по вариантам, | |
# так как на завтра мы можем есть например кашу + напиток, или легкая закуска + напиток | |
groups = array.group_by(&:variant).map do |_, mappings| | |
# сохраняем текущую погрешность | |
@diff_group = @diff.clone | |
dishes_group = mappings.map do |mapping| | |
# загружаем все блюда заданного типа с подсчитаными материалами для каждой порции | |
# выкидываем блюда которые мы выбрали раньше | |
# сортируем по наименьшему отдалению от цели по материалам с учетом погрешности | |
dish = DishesWithStats.new(mapping.dish_type).call | |
.reject { |e| @all_dishes.include?(e.id) } | |
.sort_by { |e| calc_difference(mapping.percent, e) } | |
.first | |
# обновляем погрешность | |
CALCULATOR_FIELDS.each do |sym| | |
@diff_group[sym] = calc_diff(dish, mapping.percent, sym) | |
end | |
dish | |
end | |
# возвращаем вариант с погрешностью и списком блюд | |
Group.new(@diff_group.clone, dishes_group) | |
end | |
# выбираем вариант с наименьшей погрешностью | |
group = groups.sort_by do |e| | |
CALCULATOR_FIELDS.map { |sym| e.diff[sym] }.compact.inject(:+) | |
end.first | |
# обновляем погрешность после приема пищи | |
@diff = group.diff.clone | |
# сохраняем выбранные блюда, чтобы исключить их дальнейшего подбора | |
group.dishes.map do |dish| | |
@all_dishes << dish.id | |
Variant.new(meal, dish) | |
end | |
end.flatten | |
end | |
Date::DAYNAMES.each.with_index do |day, idx| | |
variants[idx.modulo(3)].each do |variant| | |
result.result_items.create( | |
meal: variant.meal, | |
dish: variant.dish, | |
day: day, | |
portion: variant.dish.portion) | |
end | |
end | |
result | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment