Compute shipping cost with tiered pricing
Company: Stripe
Role: Data Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Technical Screen
Quick Answer: This question evaluates the ability to implement tiered billing and aggregate shipping costs across order line items, testing competencies in algorithm design, data modeling, and piecewise pricing logic including per-unit, incremental (progressive) tiers, and fixed-price tiers.
Part 1: Fixed Per-Unit Shipping Cost
Constraints
- 0 <= len(countries) == len(product_ids) == len(quantities) <= 100000
- 0 <= quantities[i] <= 1000000000
- All prices are nonnegative numbers.
- Pricing exists for every (country, product_id) pair appearing in the order.
- Return the raw numeric total; no rounding is required.
Examples
Input: (['US', 'US', 'CA'], ['A', 'B', 'A'], [2, 1, 3], {'US': {'A': 5.0, 'B': 2.5}, 'CA': {'A': 7.0}})
Expected Output: 33.5
Explanation: US/A costs 2*5.0 = 10.0, US/B costs 1*2.5 = 2.5, and CA/A costs 3*7.0 = 21.0, for a total of 33.5.
Input: ([], [], [], {})
Expected Output: 0.0
Explanation: An empty order has no line items, so the total shipping cost is 0.
Input: (['US'], ['A'], [0], {'US': {'A': 9.99}})
Expected Output: 0.0
Explanation: A line item with quantity 0 contributes no cost.
Input: (['US', 'US'], ['A', 'A'], [1, 4], {'US': {'A': 3.25}})
Expected Output: 16.25
Explanation: Both line items are charged independently: 1*3.25 + 4*3.25 = 16.25.
Hints
- Each line item is independent, so compute its cost and add it to a running total.
- Use the country first, then the product ID, to look up the unit price in the nested pricing table.
Part 2: Incremental Progressive Tier Shipping Cost
Constraints
- 0 <= len(countries) == len(product_ids) == len(quantities) <= 100000
- 0 <= quantities[i] <= 1000000000
- For each product pricing list, tiers are sorted by start_unit and do not overlap.
- Incremental tiers start at unit 1, and end_unit == -1 may appear only as the final tier.
- Pricing exists for every (country, product_id) pair appearing in the order.
Examples
Input: (['US'], ['A'], [5], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]]}})
Expected Output: 23.0
Explanation: Quantity 5 uses 3 units at 5.0 and 2 units at 4.0, giving 15.0 + 8.0 = 23.0.
Input: (['US'], ['A'], [2], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]]}})
Expected Output: 10.0
Explanation: The entire quantity falls within the first tier, so both units cost 5.0 each.
Input: (['US'], ['A'], [3], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]]}})
Expected Output: 15.0
Explanation: Quantity exactly equals the end of the first tier, so all 3 units cost 5.0 each.
Input: (['US', 'US', 'CA'], ['A', 'B', 'A'], [12, 1, 4], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]], 'B': [[1, -1, 2.5]]}, 'CA': {'A': [[1, 2, 6.0], [3, -1, 5.0]]}})
Expected Output: 73.5
Explanation: US/A quantity 12 costs 49.0, US/B quantity 1 costs 2.5, and CA/A quantity 4 costs 22.0.
Input: ([], [], [], {})
Expected Output: 0.0
Explanation: An empty order has total cost 0.
Hints
- For a line item with quantity q, only units 1 through q matter.
- For each tier, compute how many unit indices overlap with the interval [1, q].
Part 3: Mixed Fixed-Tier and Incremental Shipping Cost
Constraints
- 0 <= len(countries) == len(product_ids) == len(quantities) <= 100000
- 0 <= quantities[i] <= 1000000000
- Incremental tiers for a product are sorted, non-overlapping, and start at unit 1.
- Fixed tiers for a product are non-overlapping; if fixed_tiers omits a product, no fixed tier applies.
- If no fixed tier applies to a line item, incremental pricing exists for that line item's (country, product_id).
- A fixed tier may start at 0 to explicitly price quantity 0.
Examples
Input: (['US'], ['A'], [5], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]]}}, {'US': {'A': [[1, 5, 18.0], [6, 10, 30.0]]}})
Expected Output: 18.0
Explanation: Quantity 5 is inside the fixed tier [1, 5], so the line item costs 18.0 instead of the incremental cost 23.0.
Input: (['US'], ['A'], [12], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]]}}, {'US': {'A': [[1, 5, 18.0], [6, 10, 30.0]]}})
Expected Output: 49.0
Explanation: No fixed tier contains quantity 12, so incremental pricing is used: 3*5.0 + 7*4.0 + 2*3.0 = 49.0.
Input: (['CA'], ['A'], [0], {'CA': {'A': [[1, -1, 9.0]]}}, {'CA': {'A': [[0, 0, 0.0]]}})
Expected Output: 0.0
Explanation: Quantity 0 is explicitly covered by a fixed tier [0, 0] with fixed price 0.0.
Input: (['US', 'US', 'CA'], ['A', 'B', 'A'], [5, 3, 2], {'US': {'A': [[1, 3, 5.0], [4, 10, 4.0], [11, -1, 3.0]], 'B': [[1, -1, 2.0]]}, 'CA': {'A': [[1, 2, 6.0], [3, -1, 5.0]]}}, {'US': {'A': [[1, 5, 18.0]], 'B': [[3, 3, 5.0]]}})
Expected Output: 35.0
Explanation: US/A uses fixed 18.0, US/B quantity 3 uses fixed 5.0, and CA/A has no fixed tier so it uses incremental cost 12.0.
Input: ([], [], [], {}, {})
Expected Output: 0.0
Explanation: An empty order has total cost 0.
Hints
- The fixed-tier check should happen before any incremental calculation.
- If no fixed tier matches, reuse the same overlap calculation from progressive tier pricing.