Quick Overview

Implement tiered shipping calculator evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.

Implement tiered shipping calculator

Company: Stripe

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

Implement in JavaScript a shipping-cost calculator with three progressively richer pricing models based on a configuration object keyed by destination. 1) Flat per‑unit price: given config[destination] = { unitPrice }, return unitPrice * quantity. 2) Tiered per‑unit pricing: given config[destination] = { tiers: [ { upTo: q1, unitPrice: p1 }, { upTo: q2, unitPrice: p2 }, ..., { upTo: Infinity, unitPrice: pk } ] }, compute the total by applying each tier only to the items that fall within that tier’s range; treat each upTo as inclusive and accumulate across tiers. 3) Flat base for the first n items plus tiers afterward: given config[destination] = { baseFlat: { upTo: n, amount: F }, tiers: [...] }, charge F once for quantities 1..n; for quantities > n, charge F for the first n items and then apply tiered pricing starting from item n+1. Carefully avoid off‑by‑one mistakes at n and other tier boundaries. Define the function signature calculateShipping(destination, quantity, config) and describe tests for edge cases (quantity 0, exactly at cutoffs, unknown location, negative inputs, floating‑point handling).

Quick Answer: Implement tiered shipping calculator evaluates algorithm design, data structures, correctness, complexity, edge cases, and implementation details in a realistic interview setting. A strong answer states assumptions, handles edge cases, explains trade-offs, and shows how to validate the result clearly.

Implement `calculateShipping(destination, quantity, config)` where `config[destination]` selects one of three progressively richer pricing models: 1. **Flat per-unit**: `{ unitPrice }` -> `unitPrice * quantity`. 2. **Tiered per-unit (graduated)**: `{ tiers: [ { upTo, unitPrice }, ... ] }`. Apply each tier only to the items that fall within its range, treating each `upTo` as inclusive and accumulating across tiers (the last tier's `upTo` is an unbounded sentinel such as Infinity / a very large number). 3. **Flat base then tiers**: `{ baseFlat: { upTo: n, amount: F }, tiers: [...] }`. Charge `F` once for quantities 1..n; for quantities > n, charge `F` for the first n items and then apply tiered pricing starting from item n+1. Watch the boundaries carefully (the n+1 transition and each tier `upTo`). For an unknown destination, return null/None; for quantity <= 0, return 0.

Constraints

  • destination is a string; quantity is an integer (may be 0 or negative).
  • Exactly one of unitPrice / tiers / baseFlat+tiers is present per destination.
  • Tiers are sorted ascending by upTo; the final tier's upTo is unbounded (Infinity or a large sentinel).
  • Each upTo is inclusive; tiers are graduated (marginal), not flat-rate-of-the-whole-order.
  • Unknown destination returns null/None; quantity <= 0 returns 0.

Examples

Input: ('US', 3, {'US': {'unitPrice': 5.0}})

Expected Output: 15.0

Explanation: Flat model: unitPrice 5.0 x 3 units = 15.0.

Input: ('US', 0, {'US': {'unitPrice': 5.0}})

Expected Output: 0.0

Explanation: Edge: quantity 0 always costs 0.0 regardless of model.

Hints

  1. Dispatch on the shape of config[destination]: presence of unitPrice vs baseFlat vs tiers.
  2. For graduated tiers, track the previous tier's upTo; the current tier covers items (prev+1 .. min(upTo, quantity)).
  3. For the baseFlat model, charge F once, then start tier accounting at item n+1 — the classic off-by-one is charging item n twice or skipping item n+1.
  4. Handle quantity 0 / negative and unknown destination before touching tiers.

Loading coding console...