Pooled Rideshare Earnings With Concurrent Rides and Surge
DoorDashSoftware Engineer · Technical ScreenLast updated
Compute a pooled-ride driver's total earnings where each minute's pay scales with how many riders are currently in the car, and minutes inside non-overlapping surge windows pay double, testing sweep-line interval counting with exact half-open boundaries and 64-bit totals.
A rideshare driver works a pooled shift, ferrying overlapping sets of riders along one continuous route, and gets compensated minute by minute according to how full the car is. For any given minute, pay for that minute equals base_rate multiplied by however many riders happen to be riding along right then.
Layered on top of that are surge windows: stretches of time where whatever a minute would normally pay gets doubled, on account of high demand.
Given the base rate, the rider pickup/dropoff log, and the surge windows, work out the driver's total take-home for the shift.
Function Signature
def driver_earnings(base_rate: int, rides: list[list[int]], surge_windows: list[list[int]]) -> int:
Each rides[i] = [pickup, dropoff] places rider i in the car from minute pickup through (but excluding) minute dropoff. Each surge_windows[j] = [start, end] is active from start through (but excluding) end. Every timestamp is a whole minute on one common clock, and earnings are expressed in cents.
Rules
- Rider
ioccupies the car during exactly the minutesmsatisfyingpickup <= m < dropoff— the dropoff minute is excluded. - A surge window is in effect for exactly the minutes
msatisfyingstart <= m < end. - Define
occupancy(m)as the rider headcount during minutem. Pay for that minute isbase_rate * occupancy(m), doubled to2 * base_rate * occupancy(m)if the minute falls inside an active surge window. An empty car earns nothing for that minute, surge or not. - Sum pay across every minute to get the answer; an empty
rideslist yields0. - Rides are free to overlap in arbitrary patterns, and a ride's boundaries can land anywhere relative to a surge window, including mid-window.
Constraints
1 <= base_rate <= 5000 <= len(rides) <= 10^5, with every ride satisfying0 <= pickup < dropoff <= 10^60 <= len(surge_windows) <= 10^5, with every window satisfying0 <= start < end <= 10^6- Surge windows never overlap one another, though one is allowed to end exactly where the next begins. Input order for both lists is arbitrary.
- The final total can climb to roughly
2 * 10^14. A 32-bit counter can't hold that, so carry the running sum in 64-bit arithmetic; it still fits comfortably under2^53.
Two worked cases follow.
Examples
Example 1
Input: base_rate = 12, rides = [[5, 45], [20, 60]], surge_windows = []
Output: 960
Minutes 5-19 have 1 rider (15 minutes x 12 = 180), minutes 20-44 have 2 riders (25 minutes x 24 = 600), minutes 45-59 have 1 rider again (15 minutes x 12 = 180). Total: 180 + 600 + 180 = 960.
Example 2
Input: base_rate = 12, rides = [[5, 45], [20, 60]], surge_windows = [[30, 40]]
Output: 1200
Same rides as Example 1, but minutes 30-39 fall inside the surge window and inside the 2-rider overlap, so those 10 minutes pay 2 * 12 * 2 = 48 each instead of 24 - an extra 10 * 24 = 240 on top of Example 1's total: 960 + 240 = 1200.
Hints
Hint 1
Don't iterate minute by minute - with a timeline up to 10^6 and rides up to 10^5, think in terms of events at the handful of points where something actually changes.
Hint 2
Every ride contributes exactly two events to a sweep: one where the rider count goes up, one where it goes back down - surge windows contribute boundary points too, even though they don't change rider count themselves.
Hint 3
Sort all distinct boundary points once, then process the timeline as a sequence of constant-rate segments between consecutive points, rather than per-minute.
Hint 4
Keep 'how many riders right now' and 'is a surge window open right now' as two separate running values updated at the same sweep points.
Follow-up questions
- How would you answer repeated earnings queries over different sub-ranges of the same fixed set of rides and surge windows?
- What changes if surge windows can overlap each other, stacking the multiplier?
- How would you extend this to a per-rider pay rate instead of one shared base_rate for everyone in the car?
- How would you compute this incrementally as rides are added or removed one at a time, rather than recomputing from scratch?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.