#include <iostream>
#include <map>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
// Перечислимый тип для статуса задачи
enum class TaskStatus {
NEW, // новая
IN_PROGRESS, // в разработке
TESTING, // на тестировании
DONE // завершена
};
// Объявляем тип-синоним для map<TaskStatus, int>,
// позволяющего хранить количество задач каждого статуса
using TasksInfo = map<TaskStatus, int>;
class TeamTasks {
public:
// Получить статистику по статусам задач конкретного разработчика
const TasksInfo& GetPersonTasksInfo(const string& person) const
{
return person_tasks_.at(person);
};
// Добавить новую задачу (в статусе NEW) для конкретного разработчитка
void AddNewTask(const string& person)
{
++person_tasks_[person][TaskStatus::NEW];
};
// Обновить статусы по данному количеству задач конкретного разработчика,
// подробности см. ниже
tuple<TasksInfo, TasksInfo> PerformPersonTasks(const string& person, int task_count)
{
TasksInfo updated_tasks, untouched_tasks;
TasksInfo& tasks = person_tasks_[person];
if (person_tasks_.count(person) == 0) {
return {updated_tasks, untouched_tasks};
}
vector<TaskStatus> statuses = {TaskStatus::NEW, TaskStatus::IN_PROGRESS, TaskStatus::TESTING};
for (TaskStatus status : statuses) {
int count = tasks[status];
if (count > 0) {
int updated = min(count, task_count);
updated_tasks[static_cast<TaskStatus>(static_cast<int>(status) + 1)] += updated;
tasks[status] -= updated;
task_count -= updated;
}
}
for (const auto& [status, count] : tasks) {
if (status != TaskStatus::DONE) {
untouched_tasks[status] = count;
}
}
return {updated_tasks, untouched_tasks};
};
/*TasksInfo updated_tasks, untouched_tasks;
auto& tasks = person_tasks_[person];
for (auto status = TaskStatus::NEW; status != TaskStatus::DONE; status = static_cast<TaskStatus>(static_cast<int>(status) + 1)) {
int count = min(task_count, tasks[status]);
if (count > 0) {
updated_tasks[static_cast<TaskStatus>(static_cast<int>(status) + 1)] += count;
tasks[static_cast<TaskStatus>(static_cast<int>(status) + 1)] += count;
tasks[status] -= count;
task_count -= count;
}
if (tasks[status] > 0) {
untouched_tasks[status] = tasks[status];
}
}
return {updated_tasks, untouched_tasks};
update = (count > task_count) ? task_count : count;
count -= update;
tasks[static_cast<TaskStatus>(static_cast<int>(status) + 1)] += update;
update_tasks[status] = update;
task_count -= update;
if (task_count == 0) {
break;
}
}
for (const auto& [status, count] : tasks)
{
if (status != TaskStatus::DONE)
{
old_tasks[status] = count;
}
}
return {update_tasks, old_tasks};*/
private:
map<string, TasksInfo> person_tasks_;
};
// Принимаем словарь по значению, чтобы иметь возможность
// обращаться к отсутствующим ключам с помощью [] и получать 0,
// не меняя при этом исходный словарь.
void PrintTasksInfo(TasksInfo tasks_info) {
cout << tasks_info[TaskStatus::NEW] << " new tasks"s
<< ", "s << tasks_info[TaskStatus::IN_PROGRESS] << " tasks in progress"s
<< ", "s << tasks_info[TaskStatus::TESTING] << " tasks are being tested"s
<< ", "s << tasks_info[TaskStatus::DONE] << " tasks are done"s << endl;
}
int main() {
TeamTasks tasks;
tasks.AddNewTask("Ilia"s);
for (int i = 0; i < 3; ++i) {
tasks.AddNewTask("Ivan"s);
}
cout << "Ilia's tasks: "s;
PrintTasksInfo(tasks.GetPersonTasksInfo("Ilia"s));
cout << "Ivan's tasks: "s;
PrintTasksInfo(tasks.GetPersonTasksInfo("Ivan"s));
TasksInfo updated_tasks, untouched_tasks;
tie(updated_tasks, untouched_tasks) = tasks.PerformPersonTasks("Ivan"s, 2);
cout << "Updated Ivan's tasks: "s;
PrintTasksInfo(updated_tasks);
cout << "Untouched Ivan's tasks: "s;
PrintTasksInfo(untouched_tasks);
tie(updated_tasks, untouched_tasks) = tasks.PerformPersonTasks("Ivan"s, 2);
cout << "Updated Ivan's tasks: "s;
PrintTasksInfo(updated_tasks);
cout << "Untouched Ivan's tasks: "s;
PrintTasksInfo(untouched_tasks);
}