Implement worker time and payroll tracker
Company: Instacart
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Take-home Project
You are building an in-memory worker management module. Each worker has metadata and a history of office attendance intervals. Implement the following operations.
## Data model
Each worker has:
- `workerId` (string or int, unique)
- `title` (string)
- `salary` (number): assume this is a pay rate per unit time (e.g., dollars per hour). Pay is accrued **only while the worker is in the office**.
Time is given as an integer timestamp (monotonic within a single worker’s timeline). Attendance is tracked by **toggling** in/out:
- If the worker is currently **out** of office, a timestamp passed to `registerTime` is the **start** of a new in-office interval.
- If the worker is currently **in** the office, a timestamp passed to `registerTime` is the **end** of the current in-office interval.
Assume inputs are valid unless otherwise stated, but your design should define behavior clearly for edge cases.
## Operations to implement
### 1) Basic attendance
1. `addWorker(workerId, title, salary)`
2. `registerTime(workerId, timestamp)`
- Uses the toggle rule above to start/end an interval.
3. `getTotalInOfficeTime(workerId) -> totalTime`
- Returns the worker’s **total accumulated time** in office across all completed intervals.
### 2) Ranking by time in office
4. `topNByInOfficeTime(n) -> list`
- Returns the top `n` workers ranked by **total accumulated in-office time**.
5. `topNByInOfficeTimeForTitle(n, title) -> list`
- Same as above, but only among workers whose **current title** matches `title`.
Define your output format (e.g., list of `(workerId, totalTime)`), and specify tie-breaking.
### 3) Promotions with deferred effect
6. `promote(workerId, newTitle, newSalary)`
- A promotion is allowed to be **applied only when the worker is out of the office**.
- If the worker is currently **in** the office, the promotion must be queued and will be applied **the next time the worker enters the office** (i.e., at the next start timestamp).
- Multiple promotions may be queued for the same worker, but **only the most recent queued promotion matters** (older queued promotions are discarded/overwritten).
### 4) Payroll query
7. `getPay(workerId, startTime, endTime) -> pay`
- Returns the worker’s **total pay earned within** the time window `[startTime, endTime)`.
- Pay is computed as: for each in-office interval, take its overlap with `[startTime, endTime)` and multiply the overlap duration by the salary rate that was effective during that time.
- Promotions change the effective salary (and title) starting at the moment they are applied (per the deferred-effect rule above).
## Notes / constraints to clarify in your design
- Whether `registerTime` timestamps are guaranteed non-decreasing per worker.
- Whether incomplete intervals (worker currently in office) should be counted by `getTotalInOfficeTime` or `getPay`.
- How to handle unknown `workerId`, duplicate `addWorker`, and `startTime >= endTime`.
- Expected time complexity targets for each operation (especially `topN*` and `getPay`).
Quick Answer: This question evaluates skills in designing in-memory data structures and algorithms for temporal event handling, interval arithmetic, stateful toggles, deferred updates (queued promotions), ranking queries, and time-based payroll computation within the Coding & Algorithms domain.