Apply Item Coupons with Exact Per-Item Cent Rounding
PalantirSoftware Engineer · Online AssessmentLast updated
Implement a checkout calculation engine that applies item-specific coupons to cart lines using exact banker's rounding (round-half-to-even) per unit and returns the final cart total in integer cents.
Problem Statement
You are building the checkout pricing engine for a grocery chain's pilot discount program. Customers purchase multiple items and can scan coupons that apply discounts to specific items.
Each cart entry consists of:
item_id(string): Unique identifier for the product.unit_price_cents(integer): Base price of one unit in cents.quantity(integer): Number of units purchased.
Each coupon consists of:
coupon_id(string): Unique coupon identifier.item_id(string): The item it applies to.discount_type(string): Either"PERCENT"or"FIXED".discount_value(integer): For"PERCENT", an integer discount percentage between 1 and 100 (e.g.,20means 20% off). For"FIXED", the discount amount in cents per unit.
Application Rules
- One-to-One Matching: Each coupon applies to at most one single unit of its matching
item_id. If a customer purchases 3 units of an item and applies 2 matching coupons, 2 units receive the discount and 1 unit is charged at full price. A coupon can never be split across units or applied more than once. - Unmatched Coupons: Coupons for items not present in the cart, or surplus coupons exceeding the purchased quantity of an item, are simply ignored.
- Price Floor: The discounted price of an individual unit cannot drop below 0 cents.
- Rounding Rule (Banker's Rounding): For
"PERCENT"discounts, calculate the discount in cents as(unit_price_cents * discount_value) / 100.0. If this results in a fractional cent, round to the nearest integer cent using round-half-to-even (also known as banker's rounding). Specifically, if the fractional part is exactly0.5, round to the nearest even integer (e.g.,2.5rounds to2,3.5rounds to4). The final unit price ismax(0, unit_price_cents - rounded_discount). - If multiple coupons apply to the same
item_id, apply them in the order they appear in the coupons list.
Write a function that computes the final total cost of the cart in cents.
Function Signature
def calculate_cart_total(
cart: list[dict],
coupons: list[dict]
) -> int:
pass
Constraints
0 <= len(cart) <= 10^40 <= len(coupons) <= 10^41 <= unit_price_cents <= 10^61 <= quantity <= 10^4- For
"PERCENT",1 <= discount_value <= 100 - For
"FIXED",1 <= discount_value <= 10^6
Examples
Example 1:
cart = [
{"item_id": "apple", "unit_price_cents": 150, "quantity": 2},
{"item_id": "banana", "unit_price_cents": 75, "quantity": 1}
]
coupons = [
{"coupon_id": "c1", "item_id": "apple", "discount_type": "PERCENT", "discount_value": 15},
{"coupon_id": "c2", "item_id": "orange", "discount_type": "FIXED", "discount_value": 50}
]
# Output: 352
Explanation:
- "orange" coupon is ignored (not in cart).
- For "apple": unit 1 gets 15% off:
150 * 0.15 = 22.5. Half-to-even rounds22.5to22. Unit price =150 - 22 = 128cents. - Unit 2 of "apple" has no coupon:
150cents. - "banana": 1 unit at
75cents. - Total:
128 + 150 + 75 = 352cents.
Example 2:
cart = [
{"item_id": "milk", "unit_price_cents": 250, "quantity": 1}
]
coupons = [
{"coupon_id": "c1", "item_id": "milk", "discount_type": "PERCENT", "discount_value": 15}
]
# Output: 212
Explanation:
- Discount =
250 * 0.15 = 37.5. Nearest even integer to37.5is38. - Final price =
250 - 38 = 212cents.
Hints
Hint 1
Python's built-in `round()` function already implements round-half-to-even on floating-point numbers, but be cautious of floating-point inaccuracies (e.g., using `decimal.Decimal` with `ROUND_HALF_EVEN` avoids precision pitfalls).
Hint 2
Track remaining coupon capacity per item by matching coupons against available item units in the order coupons are provided.
Hint 3
Remember that the price floor of 0 cents applies per unit after subtracting the rounded discount amount.
Follow-up questions
- How would you modify your design if customers could stack multiple coupons on the same individual unit?
- If the store required optimal matching (i.e., assigning coupons to units to minimize total cost when coupons have different values), how would the algorithm change?
- How would you ensure determinism and auditability across different programming languages and runtimes when dealing with monetary rounding?
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.