Problem · Hash Table

Agent Task Dependency Tracker

Learn this problem
MediumPerplexity AI logoPerplexity AIFULLTIMEPHONE SCREEN

Problem statement

Process operations against an initially empty task list. Task IDs are consecutive integers starting at 1. Each task has a description and one of these statuses, in increasing order:

BLOCKED < READY_TO_EXECUTE < IN_PROGRESS < SUCCEEDED < FAILED.

  • ["ADD", description, dependencyId...] adds a task. All dependency IDs refer to earlier tasks. Its initial status is READY_TO_EXECUTE when it has no dependencies or every dependency is SUCCEEDED; otherwise it is BLOCKED. Return id:status.
  • ["GET", taskId] returns id|status|description, or NULL when the task does not exist.
  • ["SET", taskId, newStatus] changes a task's status only when the ID exists, the current status is not terminal, and newStatus is strictly higher than the current status. Return lowercase true on success and false otherwise.
  • ["RENDER"] returns the deterministic representation described below.

After a successful SET:

  • Every BLOCKED task whose direct dependencies are now all SUCCEEDED becomes READY_TO_EXECUTE.
  • If a task becomes FAILED, every currently BLOCKED task that directly or indirectly depends on it becomes FAILED.

The only transition out of BLOCKED in the operation stream is the automatic readiness or failure transition above; SET is never issued for a currently blocked task.

For RENDER, list tasks in increasing ID order, one per line, as id|status|dependencies|description. Write dependency IDs in increasing order separated by commas, or - when there are none. An empty task list renders as the empty string.

Return one output string for every input operation, in order.

Function

runAgentTodoList(operations: String[][]) → String[]

Examples

Example 1

operations = [["ADD","fetch weather"],["ADD","summarize forecast","1"],["GET","2"],["SET","1","IN_PROGRESS"],["SET","1","SUCCEEDED"],["GET","2"],["RENDER"]]return = ["1:READY_TO_EXECUTE","2:BLOCKED","2|BLOCKED|summarize forecast","true","true","2|READY_TO_EXECUTE|summarize forecast","1|SUCCEEDED|-|fetch weather\n2|READY_TO_EXECUTE|1|summarize forecast"]

Task 2 starts blocked. When task 1 succeeds, task 2 has no unfinished dependency and becomes ready. Rendering lists both tasks in ID order.

Example 2

operations = [["ADD","root"],["ADD","left","1"],["ADD","right","1"],["ADD","merge","2","3"],["SET","1","FAILED"],["GET","2"],["GET","3"],["GET","4"]]return = ["1:READY_TO_EXECUTE","2:BLOCKED","3:BLOCKED","4:BLOCKED","true","2|FAILED|left","3|FAILED|right","4|FAILED|merge"]

Failure travels through both branches of the dependency graph. The shared descendant is processed once and ends in the terminal failed state.

Constraints

  • 1 <= operations.length <= 200000.
  • There are at most 100000 ADD operations and at most 200000 total dependency references.
  • The sum, over every RENDER, of the number of tasks rendered is at most 200000.
  • Each operation has the exact form shown above.
  • Every dependency ID is a unique positive integer naming an earlier task, so the dependency graph is acyclic.
  • Descriptions are non-empty ASCII strings containing neither | nor a newline; their total length is at most 1000000.
  • taskId values and dependency IDs are canonical decimal strings without leading zeroes.
  • newStatus is one of BLOCKED, READY_TO_EXECUTE, IN_PROGRESS, SUCCEEDED, or FAILED.
  • A SET operation is never issued for a task whose current status is BLOCKED.
drafts saved locally
public String[] runAgentTodoList(String[][] operations) {
    // Write your code here.
}
operations[["ADD","fetch weather"],["ADD","summarize forecast","1"],["GET","2"],["SET","1","IN_PROGRESS"],["SET","1","SUCCEEDED"],["GET","2"],["RENDER"]]
expected["1:READY_TO_EXECUTE", "2:BLOCKED", "2|BLOCKED|summarize forecast", "true", "true", "2|READY_TO_EXECUTE|summarize forecast", "1|SUCCEEDED|-|fetch weather\n2|READY_TO_EXECUTE|1|summarize forecast"]
checking account