clanker: veet-hard-problems (run)

This commit is contained in:
kubasync-clanker 2026-02-10 18:51:21 +00:00
parent c4d74aca3e
commit de869bc230
4 changed files with 239 additions and 0 deletions

View file

@ -0,0 +1,45 @@
"""
Task Scheduler
You're building a CI/CD pipeline orchestrator. Given a set of build tasks
with durations and dependency requirements, determine the minimum total
time to complete all tasks when independent tasks can run in parallel.
Also detect if the dependency graph contains a cycle (making the build
impossible).
Each task is represented as (name, duration, dependencies) where
dependencies is a list of task names that must complete before this
task can start.
Example 1:
Input: tasks = [("compile", 3, []), ("test", 5, ["compile"]), ("lint", 2, []), ("deploy", 1, ["test", "lint"])]
Output: (9, ["compile", "test", "deploy"])
Explanation: compile(3) -> test(5) -> deploy(1) = 9. lint(2) runs in parallel and finishes before deploy starts. The critical path is compile -> test -> deploy.
Example 2:
Input: tasks = [("A", 2, ["B"]), ("B", 3, ["A"])]
Output: (-1, [])
Explanation: Circular dependency between A and B makes execution impossible.
Example 3:
Input: tasks = [("X", 4, []), ("Y", 4, []), ("Z", 1, ["X", "Y"])]
Output: (5, ["X", "Z"])
Explanation: X and Y run in parallel (both take 4). Z waits for both, then takes 1. Critical path is X(4) -> Z(1) = 5 (or equivalently Y -> Z). Return either.
Constraints:
- Task names are unique non-empty strings
- Durations are positive integers (>= 1)
- Dependencies reference other task names in the list
- Return (-1, []) if a cycle exists
- The critical path is the longest path through the dependency graph
- If multiple critical paths have the same length, return any one
- The critical path list is ordered from first task to last
- All tasks must be completed; the answer is the makespan
"""
def schedule_tasks(
tasks: list[tuple[str, int, list[str]]],
) -> tuple[int, list[str]]:
"""Return (min_total_time, critical_path) or (-1, []) if cycle exists."""
pass # Your implementation here

View file

@ -0,0 +1,79 @@
"""Tests for task-scheduler."""
import pytest
from solution import schedule_tasks
class TestBasicCases:
"""Test basic functionality with typical inputs."""
def test_example_one(self):
"""Test first example from problem description."""
tasks = [("compile", 3, []), ("test", 5, ["compile"]), ("lint", 2, []), ("deploy", 1, ["test", "lint"])]
assert schedule_tasks(tasks) == (9, ["compile", "test", "deploy"])
def test_example_two_cycle(self):
"""Test second example with circular dependency."""
tasks = [("A", 2, ["B"]), ("B", 3, ["A"])]
assert schedule_tasks(tasks) == (-1, [])
def test_example_three_parallel(self):
"""Test parallel tasks with shared dependency."""
tasks = [("X", 4, []), ("Y", 4, []), ("Z", 1, ["X", "Y"])]
cost, path = schedule_tasks(tasks)
assert cost == 5
assert path[0] in ("X", "Y") and path[-1] == "Z"
def test_linear_chain(self):
"""Test simple linear dependency chain."""
tasks = [("A", 2, []), ("B", 3, ["A"]), ("C", 4, ["B"])]
assert schedule_tasks(tasks) == (9, ["A", "B", "C"])
class TestEdgeCases:
"""Test edge cases and boundary conditions."""
def test_single_task(self):
"""Test with a single task and no dependencies."""
tasks = [("solo", 5, [])]
assert schedule_tasks(tasks) == (5, ["solo"])
def test_all_independent(self):
"""Test all tasks run in parallel with no dependencies."""
tasks = [("A", 3, []), ("B", 7, []), ("C", 5, [])]
cost, path = schedule_tasks(tasks)
assert cost == 7
assert path == ["B"]
def test_diamond_dependency(self):
"""Test diamond-shaped dependency graph."""
tasks = [("A", 1, []), ("B", 5, ["A"]), ("C", 2, ["A"]), ("D", 1, ["B", "C"])]
assert schedule_tasks(tasks) == (7, ["A", "B", "D"])
def test_three_node_cycle(self):
"""Test cycle involving three nodes."""
tasks = [("A", 1, ["C"]), ("B", 1, ["A"]), ("C", 1, ["B"])]
assert schedule_tasks(tasks) == (-1, [])
def test_wide_fan_in(self):
"""Test many tasks feeding into one final task."""
tasks = [("A", 1, []), ("B", 2, []), ("C", 3, []), ("D", 4, []), ("final", 1, ["A", "B", "C", "D"])]
assert schedule_tasks(tasks) == (5, ["D", "final"])
def test_deep_chain_with_parallel_branch(self):
"""Test long chain alongside a shorter parallel branch."""
tasks = [
("A", 1, []), ("B", 1, ["A"]), ("C", 1, ["B"]), ("D", 1, ["C"]),
("shortcut", 2, []),
("end", 1, ["D", "shortcut"]),
]
assert schedule_tasks(tasks) == (5, ["A", "B", "C", "D", "end"])
def test_partial_cycle_with_valid_tasks(self):
"""Test graph where some tasks form a cycle but others don't."""
tasks = [("A", 1, []), ("B", 2, ["C"]), ("C", 3, ["B"])]
assert schedule_tasks(tasks) == (-1, [])
def test_large_durations(self):
"""Test with large task durations."""
tasks = [("A", 1000000, []), ("B", 1000000, ["A"])]
assert schedule_tasks(tasks) == (2000000, ["A", "B"])