Compute dasher pay from order event logs
Company: DoorDash
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Take-home Project
Quick Answer: This question evaluates datetime parsing, event-stream reconstruction, state-machine reasoning for order lifecycles, and aggregation of timed intervals to compute compensation, including handling unordered timestamps, timezones, rounding, and malformed transitions.
Constraints
- 0 <= len(records) <= 200000
- Each timestamp is a valid ISO 8601 datetime string and may include a timezone offset or end with 'Z'
- If a timestamp has no timezone information, treat it as UTC
- event_type is one of CREATED, ACCEPTED, PICKED_UP, DELIVERED, CANCELED
- 0 <= rate_per_minute <= 10000, with at most 2 decimal places
Examples
Input: ([{'order_id': 'o1', 'event_type': 'DELIVERED', 'timestamp': '2024-01-01T10:31:30Z'}, {'order_id': 'o1', 'event_type': 'CREATED', 'timestamp': '2024-01-01T10:00:00Z'}, {'order_id': 'o1', 'event_type': 'ACCEPTED', 'timestamp': '2024-01-01T10:00:30Z'}, {'order_id': 'o1', 'event_type': 'PICKED_UP', 'timestamp': '2024-01-01T10:10:00Z'}], 1.5)
Expected Output: 46.5
Explanation: After sorting, order o1 is active from 10:00:30Z to 10:31:30Z, which is 31 whole minutes. Pay = 31 * 1.5 = 46.5.
Input: ([{'order_id': 'A', 'event_type': 'ACCEPTED', 'timestamp': '2024-02-01T10:00:00-05:00'}, {'order_id': 'B', 'event_type': 'DELIVERED', 'timestamp': '2024-02-01T12:00:00Z'}, {'order_id': 'C', 'event_type': 'CANCELED', 'timestamp': '2024-02-01T09:14:59+02:00'}, {'order_id': 'A', 'event_type': 'DELIVERED', 'timestamp': '2024-02-01T10:20:00-05:00'}, {'order_id': 'C', 'event_type': 'ACCEPTED', 'timestamp': '2024-02-01T09:00:00+02:00'}, {'order_id': 'B', 'event_type': 'ACCEPTED', 'timestamp': '2024-02-01T12:05:00Z'}], 2)
Expected Output: 68.0
Explanation: Order A contributes 20 minutes = 40. Order C contributes floor(14m59s) = 14 minutes = 28. Order B has DELIVERED before ACCEPTED and no later terminal event, so it is ignored. Total = 40 + 28 = 68.0.
Input: ([], 3.25)
Expected Output: 0.0
Explanation: No records means no active orders and therefore no pay.
Input: ([{'order_id': 'x', 'event_type': 'ACCEPTED', 'timestamp': '2024-03-05T10:00:00Z'}, {'order_id': 'x', 'event_type': 'PICKED_UP', 'timestamp': '2024-03-05T10:02:00Z'}, {'order_id': 'x', 'event_type': 'ACCEPTED', 'timestamp': '2024-03-05T10:03:00Z'}, {'order_id': 'x', 'event_type': 'CANCELED', 'timestamp': '2024-03-05T10:07:59Z'}, {'order_id': 'x', 'event_type': 'DELIVERED', 'timestamp': '2024-03-05T10:20:00Z'}, {'order_id': 'y', 'event_type': 'CREATED', 'timestamp': '2024-03-05T09:00:00Z'}], 1)
Expected Output: 7.0
Explanation: Order x starts at the first ACCEPTED and ends at the first later terminal event, which is CANCELED at 10:07:59Z. That is 7 whole minutes. Later DELIVERED is ignored. Order y never becomes active.
Input: ([{'order_id': 'n1', 'event_type': 'ACCEPTED', 'timestamp': '2024-03-01T10:00:00'}, {'order_id': 'n1', 'event_type': 'DELIVERED', 'timestamp': '2024-03-01T10:59:59'}, {'order_id': 'n2', 'event_type': 'ACCEPTED', 'timestamp': '2024-03-01T11:00:00Z'}, {'order_id': 'n2', 'event_type': 'DELIVERED', 'timestamp': '2024-03-01T11:00:00Z'}], 0.5)
Expected Output: 29.5
Explanation: Naive timestamps are treated as UTC. Order n1 is active for floor(59m59s) = 59 minutes, so pay is 29.5. Order n2 starts and ends at the same instant, so it contributes 0.
Hints
- Normalize every timestamp to the same timezone before comparing them.
- Group events by order_id, sort each group, then scan for the first ACCEPTED followed by the first terminal event.