Katkat

Implement multi-level task manager APIs

RampSoftware Engineer · Online Assessment

Last updated

This question evaluates implementation skills for stateful in-memory data structures, API evolution handling, substring search and prioritized sorting, and time-windowed assignment logic with quota enforcement in the Coding & Algorithms domain, and is primarily a practical application problem rather than a purely conceptual one.

You are implementing an in-memory task management system with a set of APIs that evolve over 4 levels. All APIs receive a timestamp: int parameter. Unless otherwise stated, timestamps are integers and can be assumed to be non-decreasing across calls (you may state and rely on this if needed).

Task IDs are generated sequentially as strings:

  • First task is "task_id_1", then "task_id_2", etc.
  • Creation order is the numeric suffix order (e.g., task_id_2 comes before task_id_10).

A task has:

  • name: str
  • priority: int (non-negative, >= 0)

Assignments (introduced later) are time-based.


Level 1: Basic task CRUD

Implement the following:

  1. add_task(self, timestamp: int, name: str, priority: int) -> str
  • Adds a new task with the given name and priority.
  • Returns the unique task ID.
  • Adding multiple tasks with the same name and priority is allowed; tasks are differentiated by ID.
  • Note: timestamp is unused in Level 1 logic; included for API consistency.
  1. update_task(self, timestamp: int, task_id: str, name: str, priority: int) -> bool
  • Updates the name and priority of the task identified by task_id.
  • Returns True if update succeeds; False if task_id does not exist.
  1. get_task(self, timestamp: int, task_id: str) -> str | None
  • Retrieves a task by task_id.
  • If it exists, return a JSON-formatted string containing the task details (name and priority).
  • If it does not exist, return None.

Level 2: Searching and sorting tasks

Add the following APIs:

  1. search_tasks(self, timestamp: int, name_filter: str, max_results: int) -> list[str]
  • Finds tasks whose name contains name_filter as a case-sensitive substring.
  • Returns up to max_results matching task IDs.
  • Sort results by:
  1. priority descending, then
  2. creation order ascending.
  • If max_results <= 0, return [].
  1. list_tasks_sorted(self, timestamp: int, limit: int) -> list[str]
  • Returns up to limit task IDs across the system.
  • Sorting is the same: priority descending, then creation order ascending.

Level 3: Users and time-based task assignments

Introduce users with quotas and time-windowed assignments.

  1. add_user(self, timestamp: int, user_id: str, quota: int) -> bool
  • Adds a new user with a maximum number of simultaneously active assignments (quota).
  • Returns True if added, False if user_id already exists.
  1. assign_task(self, timestamp: int, task_id: str, user_id: str, finish_time: int) -> bool
  • Assigns task_id to user_id for the time interval [timestamp, finish_time).
  • The assignment is active at time t iff start_time <= t < finish_time.
  • Returns True if successful; otherwise False if:
  • the task does not exist, or
  • the user does not exist, or
  • the user's quota is already fully used by currently active assignments.
  • Each successful active assignment consumes one quota slot while it remains active.
  1. get_user_tasks(self, timestamp: int, user_id: str) -> list[str]
  • Returns all active task IDs assigned to user_id at the given timestamp.
  • Only include assignments where start_time <= timestamp < finish_time.

Level 4: Completion and overdue detection

Add completion and overdue queries.

  1. complete_task(self, timestamp: int, task_id: str, user_id: str) -> bool
  • Marks a task as completed by user_id at time timestamp.
  • The task must be assigned to the user and active at timestamp.
  • When completed, the user's quota slot is freed immediately.
  • Returns True if successful; otherwise False if:
  • task does not exist, or
  • user does not exist, or
  • task is not assigned to the user at timestamp.
  1. get_overdue_assignments(self, timestamp: int, user_id: str) -> list[str]
  • Returns task IDs for assignments that were given to user_id and expired without completion.
  • An assignment is overdue if:
  • finish_time <= timestamp, and
  • the task was not completed before the finish_time of that specific assignment.

Implement the full system so that all levels work together consistently. Clarify any additional assumptions you need (e.g., whether timestamps are non-decreasing, whether a task can be assigned multiple times, and how repeated assignments to the same user/task should behave), but your behavior must remain consistent with the definitions above.