Skip to content

Instantly share code, notes, and snippets.

@lordhx
Created January 14, 2016 12:43
Show Gist options
  • Save lordhx/129d34859e019c3e1fbc to your computer and use it in GitHub Desktop.
Save lordhx/129d34859e019c3e1fbc to your computer and use it in GitHub Desktop.
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