Bill Deliveries with Historical Rates and Deferred Rounding

Read the full interview experience this question came from →

Quick Overview

Bill deliveries with start-time historical rates, duplicate suppression, overlapping jobs, exact sub-cent accumulation, and configurable final half-up or half-even rounding.

Bill Deliveries with Historical Rates and Deferred Rounding

Company: Rippling

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: hard

Interview Round: Technical Screen

Implement delivery billing with driver rate histories, duplicate-delivery protection, and exact accumulation before rounding. Implement `delivery_billing(operations: string[][], rounding: string) -> string[]`, returning one result string per operation. ### Operations - `["ADD",driverId,hourlyRate]`: add a new driver with an initial rate effective at time 0; return `OK`. - `["UPDATE",driverId,newRate,effectiveTime]`: add a rate change; return `OK`. - `["DELIVERY",deliveryId,driverId,start,end]`: record a delivery and its charge; return `OK` when recorded, or `IGNORED` for a duplicate already-recorded ID or a duration exceeding three hours. - `["TOTAL"]`: return the cumulative charge formatted as dollars with exactly two fractional digits. ### Constraints & Assumptions - At most 100000 operations. IDs are nonempty ASCII identifiers. ADD IDs are new, and every referenced driver exists. All times are integer seconds from 0 through 1000000000, with `0 <= start <= end`. - Rates are nonnegative dollar strings with exactly two decimal places and are at most `10000.00` per hour. - Delivery IDs are global across drivers. A recorded ID is ignored on every later DELIVERY even if its payload differs. An over-three-hour delivery is ignored without reserving its ID; this invalid-ID policy is an explicit practice choice. - Exactly three hours is valid. Overlapping deliveries for the same driver are charged independently. Zero-duration deliveries are recorded with zero cost. - Use the rate whose effective time is the greatest value not exceeding the delivery's start. A later operation at the same effective time replaces that rate for future lookups. Out-of-order effective times are allowed. - The entire delivery uses its start-time rate; do not split at a rate change. Once recorded, its charge never changes after later rate updates, including backdated updates. - Preserve fractional cents internally and round only when TOTAL returns. TOTAL must not mutate the accumulated exact amount. - `rounding` is `HALF_UP` or `HALF_EVEN`. The source did not settle exact-half-cent ties, so this practice parameter makes both policies explicit: ties round upward for HALF_UP and to the even cent for HALF_EVEN. All amounts are nonnegative. - Use integer arithmetic: a rate in cents multiplied by seconds gives an exact numerator with denominator 3600 cents. The stated bounds fit signed 64-bit arithmetic for the total numerator. ### Examples ```text operations = [["ADD","d","15.15"],["DELIVERY","a","d","0","5400"], ["TOTAL"],["DELIVERY","b","d","5400","7200"],["TOTAL"], ["DELIVERY","a","d","0","5400"],["TOTAL"]] rounding = "HALF_UP" result = ["OK","OK","22.73","OK","30.30","IGNORED","30.30"] ``` The first delivery costs exactly 22.725 dollars and the second 7.575 dollars. Their exact sum is 30.30, not the sum of individually rounded charges. For the first TOTAL alone, HALF_EVEN would return 22.72. Querying between deliveries does not change the final sum. Explain historical-rate lookup, duplicate handling, and the distinction among numeric representation, rounding time, and tie rule. For the reported debugging follow-up, describe how you would isolate a failing test: compare exact per-delivery charges, selected rate versions, duplicate IDs, and the final formatting step rather than labeling every discrepancy a floating-point issue. ```hint Keep the common denominator All durations are integer seconds and all rates are integer cents per hour. Sum exact integer numerators, then round the final quotient once per query. ```

Overview: Bill deliveries with start-time historical rates, duplicate suppression, overlapping jobs, exact sub-cent accumulation, and configurable final half-up or half-even rounding.

Read the full Rippling Software Engineer interview experience this question came from

|Home/Coding & Algorithms/Rippling
Rippling logo
Rippling
Sep 13, 2026
hardSoftware EngineerTechnical ScreenCoding & Algorithms
1
0

Implement delivery billing with driver rate histories, duplicate-delivery protection, and exact accumulation before rounding.

Implement delivery_billing(operations: string[][], rounding: string) -> string[], returning one result string per operation.

Operations

  • ["ADD",driverId,hourlyRate] : add a new driver with an initial rate effective at time 0; return OK .
  • ["UPDATE",driverId,newRate,effectiveTime] : add a rate change; return OK .
  • ["DELIVERY",deliveryId,driverId,start,end] : record a delivery and its charge; return OK when recorded, or IGNORED for a duplicate already-recorded ID or a duration exceeding three hours.
  • ["TOTAL"] : return the cumulative charge formatted as dollars with exactly two fractional digits.

Constraints & Assumptions

  • At most 100000 operations. IDs are nonempty ASCII identifiers. ADD IDs are new, and every referenced driver exists. All times are integer seconds from 0 through 1000000000, with 0 <= start <= end .
  • Rates are nonnegative dollar strings with exactly two decimal places and are at most 10000.00 per hour.
  • Delivery IDs are global across drivers. A recorded ID is ignored on every later DELIVERY even if its payload differs. An over-three-hour delivery is ignored without reserving its ID; this invalid-ID policy is an explicit practice choice.
  • Exactly three hours is valid. Overlapping deliveries for the same driver are charged independently. Zero-duration deliveries are recorded with zero cost.
  • Use the rate whose effective time is the greatest value not exceeding the delivery's start. A later operation at the same effective time replaces that rate for future lookups. Out-of-order effective times are allowed.
  • The entire delivery uses its start-time rate; do not split at a rate change. Once recorded, its charge never changes after later rate updates, including backdated updates.
  • Preserve fractional cents internally and round only when TOTAL returns. TOTAL must not mutate the accumulated exact amount.
  • rounding is HALF_UP or HALF_EVEN . The source did not settle exact-half-cent ties, so this practice parameter makes both policies explicit: ties round upward for HALF_UP and to the even cent for HALF_EVEN. All amounts are nonnegative.
  • Use integer arithmetic: a rate in cents multiplied by seconds gives an exact numerator with denominator 3600 cents. The stated bounds fit signed 64-bit arithmetic for the total numerator.

Examples

operations = [["ADD","d","15.15"],["DELIVERY","a","d","0","5400"],
 ["TOTAL"],["DELIVERY","b","d","5400","7200"],["TOTAL"],
 ["DELIVERY","a","d","0","5400"],["TOTAL"]]
rounding = "HALF_UP"
result = ["OK","OK","22.73","OK","30.30","IGNORED","30.30"]

The first delivery costs exactly 22.725 dollars and the second 7.575 dollars. Their exact sum is 30.30, not the sum of individually rounded charges. For the first TOTAL alone, HALF_EVEN would return 22.72. Querying between deliveries does not change the final sum.

Explain historical-rate lookup, duplicate handling, and the distinction among numeric representation, rounding time, and tie rule. For the reported debugging follow-up, describe how you would isolate a failing test: compare exact per-delivery charges, selected rate versions, duplicate IDs, and the final formatting step rather than labeling every discrepancy a floating-point issue.

Submit Your Answer to Earn 20XP

Sign in to leave a comment

Loading comments...