PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates skills in time-interval arithmetic, in-memory state management, and billing computation for delivery records, including handling of half-open intervals, duration-to-hour conversions, and prorated payments.

  • medium
  • Rippling
  • Coding & Algorithms
  • Software Engineer

Implement Courier Delivery Cost Tracking

Company: Rippling

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Design and implement a small in-memory cost-tracking service for food-delivery couriers. Each courier has a unique `driverId` and an `hourlyRate`. A delivery record contains a `driverId`, a `startTime`, and an `endTime`. Timestamps can be treated as numeric values such as Unix seconds or minutes. Assume `startTime < endTime`. Implement the following methods: 1. `addDriver(driverId, hourlyRate)` - Registers a courier and their hourly pay rate. 2. `recordDelivery(driverId, startTime, endTime)` - Records that the courier completed a delivery during the half-open interval `[startTime, endTime)`. - The delivery cost is proportional to the courier's hourly rate and the delivery duration. 3. `getTotalCost()` - Returns the total cost of all recorded deliveries. Pay special attention to how `startTime` and `endTime` are handled, including whether intervals are inclusive or exclusive and how duration is converted into hours. Follow-up: Add payment support: 4. `payUpTo(timestamp)` - Marks all delivery cost accrued before `timestamp` as paid. - If a delivery overlaps the timestamp, only the portion before `timestamp` is paid. 5. `getUnpaidCost()` - Returns the total cost that has been recorded but not yet paid.

Quick Answer: This question evaluates skills in time-interval arithmetic, in-memory state management, and billing computation for delivery records, including handling of half-open intervals, duration-to-hour conversions, and prorated payments.

Part 1: Implement Courier Delivery Cost Tracking

You are given a sequence of command strings for a small in-memory courier cost tracker. Each driver has a unique driverId and an hourlyRate. A delivery record uses the half-open interval [startTime, endTime), where timestamps are integer minutes and startTime < endTime. The cost of one delivery is: (hourlyRate) * (endTime - startTime) / 60 Process the commands in order: - "ADD driverId hourlyRate" registers a driver. - "RECORD driverId startTime endTime" records one delivery for that driver. - "TOTAL" asks for the total cost of all recorded deliveries so far. Return a list of answers for every TOTAL command, in order.

Constraints

  • 1 <= len(operations) <= 100000
  • 0 <= startTime < endTime <= 10^9
  • 1 <= hourlyRate <= 10^6
  • Each driverId is added at most once
  • Every RECORD command refers to a previously added driverId

Examples

Input: ["ADD d1 20", "RECORD d1 0 30", "TOTAL", "RECORD d1 30 90", "TOTAL"]

Expected Output: [10.0, 30.0]

Explanation: The first delivery lasts 30 minutes, so it costs 20 * 30 / 60 = 10. The second lasts 60 minutes and adds 20 more.

Input: ["ADD d1 15", "ADD d2 40", "RECORD d1 0 120", "RECORD d2 10 40", "TOTAL"]

Expected Output: [50.0]

Explanation: d1 costs 15 * 120 / 60 = 30. d2 costs 40 * 30 / 60 = 20. Total = 50.

Input: ["ADD d1 25", "TOTAL"]

Expected Output: [0.0]

Explanation: Edge case: no deliveries have been recorded yet.

Input: ["ADD d1 60", "RECORD d1 5 6", "TOTAL"]

Expected Output: [1.0]

Explanation: A 1-minute delivery at 60 per hour costs exactly 1.

Hints

  1. Use a hash map from driverId to hourlyRate so each RECORD can find the correct pay rate quickly.
  2. Because queries only ask for the total cost, you do not need to store every delivery; you can update one running total as deliveries are recorded.

Part 2: Add Payment Support for Accrued and Unpaid Delivery Costs

You are given a sequence of command strings for a courier cost tracker with payment support. Each driver has a unique driverId and an hourlyRate. Each delivery uses a half-open interval [startTime, endTime), where timestamps are integer minutes and startTime < endTime. The cost of one delivery is: (hourlyRate) * (endTime - startTime) / 60 Process the commands in order: - "ADD driverId hourlyRate" registers a driver. - "RECORD driverId startTime endTime" records one delivery. - "PAY timestamp" marks as paid the unpaid portion of every delivery that has already been recorded, up to that timestamp. If a delivery overlaps the timestamp, only the portion before timestamp becomes paid. - "UNPAID" asks for the total recorded cost that has not been paid yet. Important: commands are applied strictly in the given order. A PAY command affects only deliveries that have been recorded so far. If a historical delivery is recorded later, it is still unpaid until a later PAY command covers it. Return a list of answers for every UNPAID command, in order.

Constraints

  • 1 <= len(operations) <= 5000
  • 0 <= startTime < endTime <= 10^9
  • 1 <= hourlyRate <= 10^6
  • Each driverId is added at most once
  • Every RECORD command refers to a previously added driverId
  • PAY timestamps may appear in any order, and commands are processed strictly in input order

Examples

Input: ["ADD d1 60", "RECORD d1 0 30", "UNPAID", "PAY 30", "UNPAID"]

Expected Output: [30.0, 0.0]

Explanation: The delivery costs 30 total. After paying up to minute 30, the full delivery has been paid.

Input: ["ADD d1 120", "RECORD d1 0 90", "PAY 60", "UNPAID"]

Expected Output: [60.0]

Explanation: The full delivery costs 180. Paying up to minute 60 covers the first 60 minutes, which costs 120, leaving 60 unpaid.

Input: ["ADD d1 60", "ADD d2 30", "RECORD d1 0 60", "RECORD d2 30 90", "UNPAID", "PAY 45", "UNPAID", "PAY 75", "UNPAID"]

Expected Output: [90.0, 37.5, 7.5]

Explanation: Initially the unpaid total is 60 + 30 = 90. Paying to 45 covers 45 minutes of d1 and 15 minutes of d2. Paying to 75 covers the remaining 15 minutes of d1 and another 30 minutes of d2.

Input: ["ADD d1 60", "RECORD d1 10 20", "PAY 15", "PAY 12", "UNPAID"]

Expected Output: [5.0]

Explanation: Edge case: a later PAY with a smaller timestamp does not undo or double-count anything.

Input: ["ADD d1 60", "PAY 100", "RECORD d1 0 30", "UNPAID"]

Expected Output: [30.0]

Explanation: Edge case for sequential processing: the PAY command happened before the delivery was recorded, so it does not affect that later RECORD.

Hints

  1. For each delivery, store how far it has already been paid. Initially that boundary is the delivery's start time.
  2. Keep a running unpaid total. When PAY advances a delivery's paid boundary, subtract only the newly paid slice from that total.
Last updated: Jun 6, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Compare Complete and Partial Poker Hands - Rippling (medium)
  • Implement Article Vote Tracking - Rippling (medium)
  • Implement logger and card ranking - Rippling (medium)
  • Design a Driver Payroll System - Rippling (medium)
  • Compare Complete or Partial Hands - Rippling (medium)