function topologicalSort(tasks, deps) {
const taskToDeps = deps.reduce((acc, curr) => {
const [dep, task] = curr;
if (!acc.has(task)) {
acc.set(task, new Set([dep]));
} else {
acc.get(task).add(dep);
}
return acc;
}, new Map());
const depToTasks = deps.reduce((acc, curr) => {
const [dep, task] = curr;
if (!acc.has(dep)) {
acc.set(dep, new Set([task]));
} else {
acc.get(dep).add(task);
}
return acc;
}, new Map());
const tasksSet = new Set(tasks);
const tasksWithoutDependencies = Array.from(tasksSet).flatMap(task =>
taskToDeps.has(task) ? [] : task
);
let order = [];
while (order.length !== tasksSet.size) {
if (!tasksWithoutDependencies.length) {
return [];
}
const task = tasksWithoutDependencies.pop();
order.push(task);
if (depToTasks.has(task)) {
for (let taskToUpdate of depToTasks.get(task)) {
depToTasks.get(task).delete(taskToUpdate);
taskToDeps.get(taskToUpdate).delete(task);
if (!taskToDeps.get(taskToUpdate).size) {
tasksWithoutDependencies.push(taskToUpdate);
taskToDeps.delete(taskToUpdate);
}
}
depToTasks.delete(task);
}
}
return order;
}