Problems › TypeScript › pricing
Price an order across volume tiers
A wholesaler charges less per unit the more you buy, and the tiers stack: the first slice of the order is charged at the first rate, the next slice at the second, and so on.
- Tiers arrive sorted by upTo, which is a running total, not a slice width.
- A tier covers the units between where the previous tier stopped and its own upTo.
- Anything beyond the last tier is charged at the last tier rate.
- A quantity of zero or less costs nothing.
tieredTotal(qty: int, tiers: list<Tier>) → int
Where you start
function tieredTotal(qty: number, tiers: Tier[]): number {
}
Worked examples
| Call | Result |
|---|---|
tieredTotal(60, [{"upTo":10,"unitPrice":100},{"upTo":50,"unitPrice":90},{"upTo":200,"unitPrice":80}]) | 5400 |
tieredTotal(5, [{"upTo":10,"unitPrice":100},{"upTo":50,"unitPrice":90}]) | 500 |
tieredTotal(300, [{"upTo":10,"unitPrice":100},{"upTo":50,"unitPrice":90}]) | 27100 |
tieredTotal(0, [{"upTo":10,"unitPrice":100}]) | 0 |
Hint
Track how many units you have already priced. Each tier handles at most upTo minus that.
Reference solution in TypeScript
function tieredTotal(qty: number, tiers: Tier[]): number {
if (qty <= 0 || tiers.length === 0) return 0;
let done = 0;
let total = 0;
for (const t of tiers) {
const take = Math.min(qty - done, t.upTo - done);
if (take > 0) {
total += take * t.unitPrice;
done += take;
}
}
if (done < qty) total += (qty - done) * tiers[tiers.length - 1].unitPrice;
return total;
}