Bill Deliveries with Historical Rates and Deferred Rounding
RipplingSoftware Engineer · Technical ScreenLast updated
Bill deliveries with start-time historical rates, duplicate suppression, overlapping jobs, exact sub-cent accumulation, and configurable final half-up or half-even rounding.
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; returnOK.["UPDATE",driverId,newRate,effectiveTime]: add a rate change; returnOK.["DELIVERY",deliveryId,driverId,start,end]: record a delivery and its charge; returnOKwhen recorded, orIGNOREDfor 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.00per 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.
roundingisHALF_UPorHALF_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.
Hints
Hint 1
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.
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.