Katkat

Calculate Driver Payments

DoorDashSoftware Engineer · Onsite

Last updated

Implement a payout calculation system for delivery drivers by deduplicating order logs, merging overlapping active-time intervals, and computing base pay, delivery bonuses, and tips.

Problem Statement

DoorDash drivers can accept batched deliveries, meaning they may be on multiple active deliveries at the same time. You are given a list of delivery records for a driver shift, along with the driver's base hourly rate and a fixed bonus per completed delivery.

Each delivery record is represented as a dictionary with:

  • order_id (str): Unique delivery identifier.
  • start_min (int): Start time of the delivery in minutes from the beginning of the shift.
  • end_min (int): Completion time of the delivery in minutes from the beginning of the shift.
  • tip (float): Customer tip amount in dollars.

Calculate the driver's total payout according to these rules:

  1. Deduplication & Validation: Delivery logs may contain duplicate entries for the same order_id. Only process the first occurrence of any order_id and discard duplicates. Also, ignore any delivery where end_min <= start_min.
  2. Active Time Pay: Drivers earn hourly_rate for each hour of active work (hourly_rate / 60 per minute). Active time is the union of all valid delivery intervals [start_min, end_min]. If intervals overlap, time is counted only once.
  3. Delivery Bonus: The driver earns bonus_per_delivery for each unique, valid delivery completed.
  4. Tips: The driver receives 100% of all customer tips from valid, unique deliveries.

Return the total payout rounded to two decimal places.

Function Signature

def calculate_driver_payout(
    deliveries: list[dict],
    hourly_rate: float,
    bonus_per_delivery: float
) -> float:
    pass

Constraints

  • 0 <= len(deliveries) <= 10^5
  • 0 <= start_min, end_min <= 10^9
  • 0.0 <= hourly_rate <= 100.0
  • 0.0 <= bonus_per_delivery <= 50.0
  • 0.0 <= tip <= 500.0

Examples

Example 1

deliveries = [
    {"order_id": "A", "start_min": 10, "end_min": 40, "tip": 3.00},
    {"order_id": "B", "start_min": 30, "end_min": 60, "tip": 5.00},
    {"order_id": "A", "start_min": 10, "end_min": 40, "tip": 3.00}, # duplicate
    {"order_id": "C", "start_min": 50, "end_min": 50, "tip": 2.00}  # invalid duration
]
hourly_rate = 18.00
bonus_per_delivery = 2.00

Output: 27.00

Explanation:

  • Valid unique deliveries: "A" ([10, 40], tip $3.00) and "B" ([30, 60], tip $5.00).
  • Merged active interval: [10, 60] -> 50 active minutes.
  • Active pay: (50 / 60) * 18.00 = 15.00
  • Delivery bonus: 2 * 2.00 = 4.00
  • Tips: 3.00 + 5.00 = 8.00
  • Total payout: 15.00 + 4.00 + 8.00 = 27.00

Hints

Hint 1

Deduplicate deliveries using a set of seen order IDs and filter out records where end_min is less than or equal to start_min.

Hint 2

Sort the remaining valid intervals by start time to merge overlapping intervals and compute the total active minutes without double counting.

Hint 3

Accumulate tips, bonus counts, and active time pay separately before rounding the final sum to two decimal places.

Follow-up questions

  • How would you handle this calculation in a streaming architecture where delivery status events arrive out of order and driver pay needs to be updated in real time?
  • How can you avoid floating-point precision issues when processing millions of transactions (e.g., using integer cents or Decimal types)?
  • How would you extend this logic if DoorDash introduced dynamic pay multipliers during peak hours (e.g., 1.5x hourly pay between minutes 120 and 240)?