Skip to content

Instantly share code, notes, and snippets.

@tatsuyax25
Created May 1, 2025 17:41
Show Gist options
  • Save tatsuyax25/e0ab0d30b043265124084bd013ae3769 to your computer and use it in GitHub Desktop.
Save tatsuyax25/e0ab0d30b043265124084bd013ae3769 to your computer and use it in GitHub Desktop.
You have n tasks and m workers. Each task has a strength requirement stored in a 0-indexed integer array tasks, with the ith task requiring tasks[i] strength to complete. The strength of each worker is stored in a 0-indexed integer array workers, wit
/**
* Determines the maximum number of tasks that can be assigned given workers and pills.
*
* @param {number[]} tasks - Array of task difficulties.
* @param {number[]} workers - Array of worker strengths.
* @param {number} pills - Number of strength-boosting pills available.
* @param {number} strength - Strength increase provided by each pill.
* @return {number} - Maximum number of tasks that can be assigned.
*/
var maxTaskAssign = function(tasks, workers, pills, strength) {
// Sort tasks and workers in ascending order for efficient pairing
tasks.sort((a, b) => a - b);
workers.sort((a, b) => a - b);
/**
* Helper function to check if 'mid' number of tasks can be assigned.
* @param {number} mid - Number of tasks to attempt to assign.
* @return {boolean} - True if 'mid' tasks can be assigned, otherwise false.
*/
const canAssign = (mid) => {
// Get the 'mid' strongest workers, sorted in ascending order
let usableWorkers = workers.slice(-mid).sort((a, b) => a - b);
let remainingPills = pills;
// Try assigning tasks starting from the hardest one within 'mid'
for (let i = mid - 1; i >= 0; i--) {
let task = tasks[i];
if (usableWorkers[usableWorkers.length - 1] >= task) {
// Use the strongest available worker
usableWorkers.pop();
} else {
// If no pills left, assignment fails
if (remainingPills <= 0) return false;
// Find the weakest worker who can handle the task with a pill
let left = 0, right = usableWorkers.length - 1;
let idx = usableWorkers.length;
while (left <= right) {
let m = Math.floor((left + right) / 2);
if (usableWorkers[m] + strength >= task) {
idx = m;
right = m - 1;
} else {
left = m + 1;
}
}
// If no suitable worker found, assignment fails
if (idx === usableWorkers.length) return false;
// Use the pill on the selected worker and remove them from the pool
usableWorkers.splice(idx, 1);
remainingPills--;
}
}
return true;
};
// Perform binary search to find the maximum assignable tasks
let low = 0, high = Math.min(tasks.length, workers.length);
let assigned = 0;
while (low <= high) {
let mid = Math.floor((low + high) / 2);
if (canAssign(mid)) {
// If 'mid' tasks can be assigned, try increasing the assignment count
assigned = mid;
low = mid + 1;
} else {
// Otherwise, reduce the task count to attempt assignment
high = mid - 1;
}
}
return assigned;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment