From 6dc2ccbb55c0ab53c8ab954f9ab2b9804cd2d7e2 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Thu, 20 Aug 2026 08:21:15 +0300 Subject: [PATCH] spread heavy workload days --- .../Schedule/EvenDistributionScheduler.php | 106 +++++++++++------- .../CreateSchedule/CreateSchedule.php | 12 -- 2 files changed, 65 insertions(+), 53 deletions(-) diff --git a/backend/app/Schedule/EvenDistributionScheduler.php b/backend/app/Schedule/EvenDistributionScheduler.php index 5030655..3cdb919 100644 --- a/backend/app/Schedule/EvenDistributionScheduler.php +++ b/backend/app/Schedule/EvenDistributionScheduler.php @@ -18,15 +18,7 @@ class EvenDistributionScheduler $differenceInDays = $startDate->diff($targetDate)->days; $dayCount = $differenceInDays + 1; - if ($workloadPlacement === WorkloadPlacement::Spread) { - return $this->sparseDates( - assignmentCount: $assignmentCount, - dayCount: $dayCount, - startDate: $startDate, - ); - } - - return $this->groupedDates( + return $this->distributedDates( assignmentCount: $assignmentCount, dayCount: $dayCount, startDate: $startDate, @@ -37,33 +29,7 @@ class EvenDistributionScheduler /** * @return list */ - private function sparseDates( - int $assignmentCount, - int $dayCount, - DateTimeImmutable $startDate, - ): array { - if ($assignmentCount === 1) { - return [$startDate]; - } - - $dates = []; - for ($assignmentIndex = 0; - $assignmentIndex < $assignmentCount; - $assignmentIndex++ - ) { - $scaledIndex = $assignmentIndex * ($dayCount - 1) - / ($assignmentCount - 1); - $dayIndex = (int) floor($scaledIndex + 0.5); - $dates[] = $startDate->modify("+{$dayIndex} days"); - } - - return $dates; - } - - /** - * @return list - */ - private function groupedDates( + private function distributedDates( int $assignmentCount, int $dayCount, DateTimeImmutable $startDate, @@ -71,19 +37,18 @@ class EvenDistributionScheduler ): array { $assignmentsPerDay = intdiv($assignmentCount, $dayCount); $remainderDayCount = $assignmentCount % $dayCount; - $remainderBlockStart = $this->remainderBlockStart( + $remainderDayIndexes = $this->remainderDayIndexes( + assignmentsPerDay: $assignmentsPerDay, dayCount: $dayCount, remainderDayCount: $remainderDayCount, workloadPlacement: $workloadPlacement, ); + $remainderDays = array_fill_keys($remainderDayIndexes, true); $dates = []; for ($dayIndex = 0; $dayIndex < $dayCount; $dayIndex++) { $assignmentCountForDay = $assignmentsPerDay; - if ( - $dayIndex >= $remainderBlockStart - && $dayIndex < $remainderBlockStart + $remainderDayCount - ) { + if (isset($remainderDays[$dayIndex])) { $assignmentCountForDay++; } @@ -96,6 +61,65 @@ class EvenDistributionScheduler return $dates; } + /** + * @return list + */ + private function remainderDayIndexes( + int $assignmentsPerDay, + int $dayCount, + int $remainderDayCount, + WorkloadPlacement $workloadPlacement, + ): array { + if ($remainderDayCount === 0) { + return []; + } + + if ($workloadPlacement === WorkloadPlacement::Spread) { + return $this->spreadRemainderDayIndexes( + assignmentsPerDay: $assignmentsPerDay, + dayCount: $dayCount, + remainderDayCount: $remainderDayCount, + ); + } + + $blockStart = $this->remainderBlockStart( + dayCount: $dayCount, + remainderDayCount: $remainderDayCount, + workloadPlacement: $workloadPlacement, + ); + + return range($blockStart, $blockStart + $remainderDayCount - 1); + } + + /** + * @return list + */ + private function spreadRemainderDayIndexes( + int $assignmentsPerDay, + int $dayCount, + int $remainderDayCount, + ): array { + if ($remainderDayCount === 1) { + if ($assignmentsPerDay === 0) { + return [0]; + } + + return [intdiv($dayCount - 1, 2)]; + } + + $dayIndexes = []; + for ($remainderIndex = 0; + $remainderIndex < $remainderDayCount; + $remainderIndex++ + ) { + $scaledIndex = $remainderIndex * ($dayCount - 1) + / ($remainderDayCount - 1); + $dayIndexes[] = (int) floor($scaledIndex + 0.5); + } + + return $dayIndexes; + } + private function remainderBlockStart( int $dayCount, int $remainderDayCount, diff --git a/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php b/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php index e131aa4..fe9392a 100644 --- a/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php +++ b/backend/app/Schedule/UseCases/CreateSchedule/CreateSchedule.php @@ -248,9 +248,6 @@ class CreateSchedule return $workloadPlacement; } - /** - * @throws BadRequestException - */ private function resolvedWorkloadPlacement( ?WorkloadPlacement $requestedWorkloadPlacement, int $assignmentCount, @@ -267,15 +264,6 @@ class CreateSchedule : WorkloadPlacement::Middle; } - if ( - $requestedWorkloadPlacement === WorkloadPlacement::Spread - && ! $isSparse - ) { - throw new BadRequestException( - 'spread placement requires fewer assignments than days', - ); - } - return $requestedWorkloadPlacement; } }