github-actions[bot]
chore: sync uc-hospital Space
7596726
use chrono::NaiveDate;
use std::cmp::Reverse;
use std::collections::{BTreeMap, BTreeSet};
use crate::domain::Employee;
use super::support::{can_mark_preference_date, mark_preference_date, PreferenceKind};
/// Ensures every employee ends up with the minimum amount of preference signal.
pub(super) fn ensure_preference_floor(
employees: &mut [Employee],
witness_dates_by_employee: &[BTreeSet<NaiveDate>],
coverable_dates_by_employee: &[BTreeSet<NaiveDate>],
date_pressure: &BTreeMap<NaiveDate, usize>,
) {
for employee_index in 0..employees.len() {
while employees[employee_index].undesired_dates.len() < 4 {
let candidate = witness_dates_by_employee[employee_index]
.iter()
.chain(coverable_dates_by_employee[employee_index].iter())
.copied()
.filter(|&date| {
can_mark_preference_date(
&employees[employee_index],
date,
PreferenceKind::Undesired,
)
})
.max_by_key(|date| (*date_pressure.get(date).unwrap_or(&0), Reverse(*date)));
let Some(date) = candidate else {
break;
};
let _ = mark_preference_date(
&mut employees[employee_index],
date,
PreferenceKind::Undesired,
);
}
while employees[employee_index].desired_dates.len() < 4 {
let candidate = coverable_dates_by_employee[employee_index]
.iter()
.copied()
.filter(|&date| !witness_dates_by_employee[employee_index].contains(&date))
.filter(|&date| {
can_mark_preference_date(
&employees[employee_index],
date,
PreferenceKind::Desired,
)
})
.max_by_key(|date| (*date_pressure.get(date).unwrap_or(&0), Reverse(*date)))
.or_else(|| {
coverable_dates_by_employee[employee_index]
.iter()
.copied()
.filter(|&date| {
can_mark_preference_date(
&employees[employee_index],
date,
PreferenceKind::Desired,
)
})
.max_by_key(|date| (*date_pressure.get(date).unwrap_or(&0), Reverse(*date)))
});
let Some(date) = candidate else {
break;
};
let _ = mark_preference_date(
&mut employees[employee_index],
date,
PreferenceKind::Desired,
);
}
}
}