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
Go needs a compiler and Drill does not host one yet, so this page is the reference rather than an exercise: the problem, worked examples, and the solution in full. To type it out, the same problem runs in Python.
Where you start
func tieredTotal(qty int, tiers []Tier) int {
}
Worked examples
| Call | Result |
|---|---|
tieredTotal(60, []Tier{Tier{UpTo: 10, UnitPrice: 100}, Tier{UpTo: 50, UnitPrice: 90}, Tier{UpTo: 200, UnitPrice: 80}}) | 5400 |
tieredTotal(5, []Tier{Tier{UpTo: 10, UnitPrice: 100}, Tier{UpTo: 50, UnitPrice: 90}}) | 500 |
tieredTotal(300, []Tier{Tier{UpTo: 10, UnitPrice: 100}, Tier{UpTo: 50, UnitPrice: 90}}) | 27100 |
tieredTotal(0, []Tier{Tier{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 Go
func tieredTotal(qty int, tiers []Tier) int {
if qty <= 0 || len(tiers) == 0 {
return 0
}
done, total := 0, 0
for _, t := range tiers {
take := qty - done
if t.UpTo-done < take {
take = t.UpTo - done
}
if take > 0 {
total += take * t.UnitPrice
done += take
}
}
if done < qty {
total += (qty - done) * tiers[len(tiers)-1].UnitPrice
}
return total
}