private JobQueueReport[] AssignJobs(int numWorkers, int[] jobs)
        {
            // TODO: replace this code with a faster algorithm.
            var reports = new JobQueueReport[jobs.Length];

            long[] nextFreeTime = new long[numWorkers];
            for (int i = 0; i < jobs.Length; i++)
            {
                int duration   = jobs[i];
                int bestWorker = 0;
                for (int j = 0; j < numWorkers; ++j)
                {
                    if (nextFreeTime[j] < nextFreeTime[bestWorker])
                    {
                        bestWorker = j;
                    }
                }
                reports[i] = new JobQueueReport(assignedWorker: bestWorker, startTime: nextFreeTime[bestWorker]);
                nextFreeTime[bestWorker] += duration;
            }
            return(reports);
        }
        private JobQueueReport[] _AssignJobs(int numWorkers, int[] jobs)
        {
            // TODO: replace this code with a faster algorithm.
            var reports = new JobQueueReport[jobs.Length];
            var heap    = new PriorityQueue <JobQueueWorker>(numWorkers);

            for (int i = 0; i < numWorkers; i++)
            {
                heap.Insert(new JobQueueWorker(id: i));
            }

            for (int i = 0; i < jobs.Length; i++)
            {
                int duration   = jobs[i];
                var bestWorker = heap.GetMax();

                reports[i] = new JobQueueReport(assignedWorker: bestWorker.Id, startTime: bestWorker.NextFreeTime);
                bestWorker.NextFreeTime += duration;

                heap.UpdateMax();
            }
            return(reports);
        }