Skip to content

Commit

Permalink
limiting scheduling on max_per_day/week
Browse files Browse the repository at this point in the history
...but now sleep_1 is failing
  • Loading branch information
Tijl Leenders committed Jan 14, 2024
1 parent 3215649 commit 49439f7
Show file tree
Hide file tree
Showing 5 changed files with 465 additions and 523 deletions.
68 changes: 62 additions & 6 deletions src/models/activity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use std::{

#[derive(Clone)]
pub struct Activity {
pub id: String,
pub goal_id: String,
pub title: String,
pub min_block_size: usize,
pub max_block_size: usize,
Expand Down Expand Up @@ -122,6 +122,9 @@ impl Activity {
for offset in 0..self.total_duration {
match &self.calendar_overlay[hour_index + offset] {
None => {
// panic!("Does this ever happen?");
// Yes in algorithm_challenge test case
// TODO: do we need to mark all from hour_index till offset as None?"
continue;
}
Some(weak) => {
Expand Down Expand Up @@ -204,7 +207,7 @@ impl Activity {
);

let activity = Activity {
id: goal.id.clone(),
goal_id: goal.id.clone(),
title: goal.title.clone(),
min_block_size: 1,
max_block_size: 1,
Expand Down Expand Up @@ -247,7 +250,7 @@ impl Activity {
);

let activity = Activity {
id: goal.id.clone(),
goal_id: goal.id.clone(),
title: goal.title.clone(),
min_block_size,
max_block_size: min_block_size,
Expand All @@ -264,11 +267,64 @@ impl Activity {
}

pub fn update_overlay_with(&mut self, budgets: &Vec<Budget>) -> () {
if self.status == Status::Scheduled || self.status == Status::Impossible {
//return - no need to update overlay
return ();
}
for budget in budgets {
//check my overlay for valid placing options
//check placing option with budget
//if not allowed set all hours to None
if budget.participating_goals.contains(&self.goal_id) {
// great, process it
} else {
// budget not relevant to this activity
continue;
}
//check if activity goal id is in the budget - else don't bother
//check my overlay for valid placing options, with a loop like get_best_scheduling_index
for hour_index in 0..self.calendar_overlay.len() {
match &self.calendar_overlay[hour_index] {
None => {
continue;
}
Some(_) => {
for offset in 0..self.total_duration {
match &self.calendar_overlay[hour_index + offset] {
None => {
//empty block found < min_block_size
self.set_overlay_to_none(hour_index.clone(), offset);
continue;
}
Some(weak) => {
if weak.upgrade().is_none() {
//empty block found < min_block_size
self.set_overlay_to_none(hour_index.clone(), offset);
break;
}
//if last position check if best so far - or so little we can break
if offset == self.min_block_size - 1 {
//check if not allowed by budgets
let is_allowed =
budget.is_within_budget(hour_index, offset);
if is_allowed {
// Cool!
} else {
self.set_overlay_to_none(hour_index.clone(), offset);
}
continue;
}
}
}
}
}
}
}
}
}

fn set_overlay_to_none(&mut self, start_index: usize, offset: usize) -> () {
for index in start_index..start_index + 1 {
self.calendar_overlay[index] = None;
}
()
}
}

Expand Down
21 changes: 20 additions & 1 deletion src/models/budget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub struct Budget {
}
impl Budget {
pub fn reduce_for_(&mut self, goal: &str, duration_offset: usize) -> () {
if self.participating_goals.contains(&goal.clone().to_string()) {
if self.participating_goals.contains(&goal.to_string()) {
let mut time_budgets_updated = self.time_budgets.clone();
for time_budget_index in 0..self.time_budgets.len() {
if duration_offset >= self.time_budgets[time_budget_index].calendar_start_index
Expand All @@ -35,6 +35,25 @@ impl Budget {
self.time_budgets = time_budgets_updated;
}
}

pub(crate) fn is_within_budget(&self, hour_index: usize, offset: usize) -> bool {
let mut is_allowed = true;
for time_budget in &self.time_budgets {
//figure out how many of the hours in hour_index till hour_index + offset are in the time_budget window
let mut hours_in_time_budget_window = 0;
for local_offset in 0..offset {
if (hour_index + local_offset) >= time_budget.calendar_start_index
&& (hour_index + local_offset) < time_budget.calendar_end_index
{
hours_in_time_budget_window += 1;
}
}
if time_budget.scheduled + hours_in_time_budget_window >= time_budget.max_scheduled {
is_allowed = false;
}
}
is_allowed
}
}

#[derive(Deserialize, Debug, Clone)]
Expand Down
7 changes: 4 additions & 3 deletions src/services/activity_placer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ pub fn place(mut calendar: &mut Calendar, mut activities: Vec<Activity>) -> () {
if best_hour_index.is_none() {
activities[act_index_to_schedule.unwrap()].status = Status::Impossible;
activities[act_index_to_schedule.unwrap()].release_claims();
//TODO: Only add to impossible if not an optional activity
let impossible_activity = ImpossibleActivity {
id: activities[act_index_to_schedule.unwrap()].id.clone(),
id: activities[act_index_to_schedule.unwrap()].goal_id.clone(),
title: activities[act_index_to_schedule.unwrap()].title.clone(),
min_block_size: activities[act_index_to_schedule.unwrap()].min_block_size,
};
Expand Down Expand Up @@ -58,11 +59,11 @@ pub fn place(mut calendar: &mut Calendar, mut activities: Vec<Activity>) -> () {
calendar.hours[best_hour_index.unwrap() + duration_offset] = Rc::new(Hour::Occupied {
activity_index: act_index_to_schedule.unwrap(),
activity_title: activities[act_index_to_schedule.unwrap()].title.clone(),
activity_goalid: activities[act_index_to_schedule.unwrap()].id.clone(),
activity_goalid: activities[act_index_to_schedule.unwrap()].goal_id.clone(),
});
//TODO: activity doesn't need to know about time_budets => remove completely
calendar.update_budgets_for(
&activities[act_index_to_schedule.unwrap()].id.clone(),
&activities[act_index_to_schedule.unwrap()].goal_id.clone(),
best_hour_index.unwrap() + duration_offset,
);
(activities[act_index_to_schedule.unwrap()]).release_claims();
Expand Down
Loading

0 comments on commit 49439f7

Please sign in to comment.