Schedule prerequisite classes with retakes
Company: Snowflake
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Onsite
## Problem
You are building a course-taking engine.
Each course is represented as an object:
- `id` (unique identifier)
- `prevCoursesList`: a list of prerequisite course IDs that must be **passed** before this course can be attempted.
You are given:
- `roots`: a list of **target** course IDs the student ultimately wants to complete.
- An API `didPass(courseId) -> bool` that can be called **each time you attempt** a course. If it returns `false`, the student failed that attempt and must retake the course later.
### Rules
1. A course can be **attempted** only after all its prerequisites have been **passed**.
2. When a course is attempted:
- If `didPass(id)` returns `true`, mark it as passed.
- If it returns `false`, the course must be retaken later (i.e., re-queued for another attempt).
3. The input only provides prerequisite pointers (`course -> prerequisites`). You must first discover all involved courses reachable from `roots` and build any additional relationships you need (e.g., prerequisite → dependent adjacency).
### Task
Implement a function that returns the sequence of course IDs in the order they were **attempted** until:
- all `roots` have been passed, or
- you detect it is impossible (e.g., a prerequisite cycle), or
- a course exceeds `maxRetries` failed attempts.
### Output
Return:
- `attemptOrder`: list of attempted course IDs (including retries), if successful.
- Otherwise, return/throw an error indicating the reason (cycle detected or retries exceeded).
### Constraints (reasonable assumptions)
- Up to ~1e5 courses and ~2e5 prerequisite edges may be involved after expanding from `roots`.
- `maxRetries` is a small integer (e.g., 3–10).
### Edge cases to handle
- Shared prerequisites among multiple roots.
- Duplicate IDs in `roots`.
- Missing prerequisite IDs (treat as invalid input).
- Cycles in prerequisite dependencies.
- Courses that repeatedly fail and exceed `maxRetries`.
Quick Answer: This question evaluates competency in graph algorithms, dependency resolution, stateful scheduling, and robust error handling within the Coding & Algorithms domain.