Compute shipping cost with tiered pricing
Company: Stripe
Role: Data Engineer
Category: Coding & Algorithms
Interview Round: Technical Screen
Quick Answer: Evaluates implementation-level algorithmic logic for tiered pricing, covering per-unit aggregation, interval reasoning, and mixed incremental vs fixed pricing models within the Coding & Algorithms domain and Data Engineering role; abstraction level is practical, implementation-focused business logic and data transformation.
Part 1: Fixed Per-Unit Shipping
Constraints
- 0 <= len(order_lines), len(unit_rates) <= 100000
- Each order line has quantity >= 1
- unit_price is a non-negative int or float
- For a given (country, product), assume unit_rates contains at most one matching rate
- If a rate is missing for a (country, product) pair, treat its shipping cost as 0
Examples
Input: ([{'country': 'US', 'product': 'book', 'quantity': 2}, {'country': 'US', 'product': 'toy', 'quantity': 3}, {'country': 'CA', 'product': 'book', 'quantity': 1}], [{'country': 'US', 'product': 'book', 'unit_price': 4}, {'country': 'US', 'product': 'toy', 'unit_price': 2}, {'country': 'CA', 'product': 'book', 'unit_price': 5}])
Expected Output: 19
Explanation: Shipping is 2*4 + 3*2 + 1*5 = 19.
Input: ([{'country': 'JP', 'product': 'pen', 'quantity': 1}], [{'country': 'JP', 'product': 'pen', 'unit_price': 7}])
Expected Output: 7
Explanation: Single order line with the minimum quantity boundary.
Input: ([{'country': 'US', 'product': 'book', 'quantity': 2}, {'country': 'FR', 'product': 'game', 'quantity': 4}], [{'country': 'US', 'product': 'book', 'unit_price': 3}])
Expected Output: 6
Explanation: The FR/game rate is missing, so that line contributes 0. Total = 2*3 = 6.
Input: ([], [{'country': 'US', 'product': 'book', 'unit_price': 4}])
Expected Output: 0
Explanation: Edge case: no order lines means total shipping cost is 0.
Hints
- A dictionary keyed by (country, product) lets you find each rate in O(1) average time.
- First preprocess unit_rates, then make a single pass through order_lines.
Part 2: Incremental Tiered Shipping
Constraints
- 0 <= len(order_lines), len(incremental_tiers) <= 100000
- Each order line has quantity >= 1
- For each tier, 1 <= start_qty <= end_qty
- unit_price is a non-negative int or float
- For the same (country, product), incremental tiers do not overlap
- If a pair is missing or some units are uncovered by tiers, those units cost 0
Examples
Input: ([{'country': 'US', 'product': 'book', 'quantity': 5}], [{'country': 'US', 'product': 'book', 'start_qty': 1, 'end_qty': 3, 'unit_price': 5}, {'country': 'US', 'product': 'book', 'start_qty': 4, 'end_qty': 10, 'unit_price': 3}])
Expected Output: 21
Explanation: Units 1-3 cost 5 each and units 4-5 cost 3 each, so total = 15 + 6 = 21.
Input: ([{'country': 'US', 'product': 'book', 'quantity': 5}, {'country': 'CA', 'product': 'toy', 'quantity': 4}], [{'country': 'US', 'product': 'book', 'start_qty': 1, 'end_qty': 3, 'unit_price': 5}, {'country': 'US', 'product': 'book', 'start_qty': 4, 'end_qty': 10, 'unit_price': 3}, {'country': 'CA', 'product': 'toy', 'start_qty': 1, 'end_qty': 2, 'unit_price': 1}, {'country': 'CA', 'product': 'toy', 'start_qty': 3, 'end_qty': 4, 'unit_price': 2}])
Expected Output: 27
Explanation: US/book costs 21. CA/toy costs 2*1 + 2*2 = 6. Total = 27.
Input: ([{'country': 'US', 'product': 'lamp', 'quantity': 5}], [{'country': 'US', 'product': 'lamp', 'start_qty': 1, 'end_qty': 5, 'unit_price': 4}])
Expected Output: 20
Explanation: Edge-style boundary case: the whole quantity falls into one inclusive tier, so cost = 5*4 = 20.
Input: ([], [{'country': 'US', 'product': 'book', 'start_qty': 1, 'end_qty': 3, 'unit_price': 5}])
Expected Output: 0
Explanation: Edge case: no order lines means total shipping cost is 0.
Hints
- Do not simulate each unit one by one. Instead, compute how many unit indexes from 1..Q overlap each tier interval.
- Group tiers by (country, product) so each order line only scans relevant tiers.
Part 3: Mixed Pricing Models - Fixed Total vs Incremental
Constraints
- 0 <= len(order_lines), len(tiers) <= 100000
- Each order line has quantity >= 1
- For each tier, 1 <= start_qty <= end_qty
- price is a non-negative int or float
- For the same (country, product), fixed tiers do not overlap each other
- For the same (country, product), incremental tiers do not overlap each other
- If a fixed tier applies, ignore incremental tiers for that order line
- If no fixed tier applies and some units are uncovered by incremental tiers, those units cost 0
Examples
Input: ([{'country': 'US', 'product': 'book', 'quantity': 6}], [{'country': 'US', 'product': 'book', 'start_qty': 6, 'end_qty': 10, 'pricing_type': 'fixed', 'price': 20}, {'country': 'US', 'product': 'book', 'start_qty': 1, 'end_qty': 3, 'pricing_type': 'incremental', 'price': 5}, {'country': 'US', 'product': 'book', 'start_qty': 4, 'end_qty': 10, 'pricing_type': 'incremental', 'price': 3}])
Expected Output: 20
Explanation: Boundary-inclusive fixed tier applies because Q = 6 is inside [6, 10], so the whole line costs 20.
Input: ([{'country': 'US', 'product': 'book', 'quantity': 5}], [{'country': 'US', 'product': 'book', 'start_qty': 6, 'end_qty': 10, 'pricing_type': 'fixed', 'price': 20}, {'country': 'US', 'product': 'book', 'start_qty': 1, 'end_qty': 3, 'pricing_type': 'incremental', 'price': 5}, {'country': 'US', 'product': 'book', 'start_qty': 4, 'end_qty': 10, 'pricing_type': 'incremental', 'price': 3}])
Expected Output: 21
Explanation: No fixed tier matches Q = 5, so use incremental pricing: 3*5 + 2*3 = 21.
Input: ([{'country': 'US', 'product': 'book', 'quantity': 6}, {'country': 'US', 'product': 'book', 'quantity': 4}, {'country': 'CA', 'product': 'toy', 'quantity': 2}], [{'country': 'US', 'product': 'book', 'start_qty': 6, 'end_qty': 10, 'pricing_type': 'fixed', 'price': 20}, {'country': 'US', 'product': 'book', 'start_qty': 1, 'end_qty': 3, 'pricing_type': 'incremental', 'price': 5}, {'country': 'US', 'product': 'book', 'start_qty': 4, 'end_qty': 10, 'pricing_type': 'incremental', 'price': 3}, {'country': 'CA', 'product': 'toy', 'start_qty': 1, 'end_qty': 1, 'pricing_type': 'fixed', 'price': 9}, {'country': 'CA', 'product': 'toy', 'start_qty': 1, 'end_qty': 5, 'pricing_type': 'incremental', 'price': 2}])
Expected Output: 42
Explanation: US/book qty 6 uses fixed = 20. US/book qty 4 uses incremental = 3*5 + 1*3 = 18. CA/toy qty 2 does not match its fixed tier, so it uses incremental = 2*2 = 4. Total = 42.
Input: ([], [{'country': 'US', 'product': 'book', 'start_qty': 6, 'end_qty': 10, 'pricing_type': 'fixed', 'price': 20}])
Expected Output: 0
Explanation: Edge case: no order lines means total shipping cost is 0.
Hints
- Store fixed tiers and incremental tiers separately for each (country, product) pair.
- For each order line, check fixed tiers first. Only if none match should you compute incremental overlap.