Оптимизационная задача

Перед студентами курса "Практика программирования с использованием С++" каждый семестр возникает проблема решения оптимизационной задачи. Разработайте функцию
auto solve_optimization_task(std::pair<size_t, size_t>),
принимающую количество его баллов (основных и дополнительных) в формате std::pair<size_t, size_t>, и возвращающую std::tuple, содержащий от 0 до 3 объектов: баллы, направленные на засчитывание КВ, и от 0 до 2 булевых значений true, обозначающие задачу, засчитанную автоматом. Не стоит забывать о том, что дополнительные баллы можно превращать в основные, если это требуется.

Также реализуйте перегрузку этой функции, принимающую ещё и шаблонный параметр — класс студента, для которого гарантируется наличие методов desired_mark(), skills() и knowledge(). Если желаемая оценка уже набрана, то «лишние» баллы следует оставить нетронутыми, т.е. КВ и/или задачи засчитывать не нужно. Метод knowledge() возвращает уровень знаний студента — вероятность успешного ответа на КВ (в процентах), аналогично метод skills() показывает умение студента решать задачи. Требуется достичь не менее 80% вероятности успешной сдачи зачёта. Если это невозможно, необходимо выбросить исключение с указанием максимально достижимого процента успеха.