Pick the coupon worth most
A customer has several coupons in their wallet and the checkout applies whichever saves them the most on this basket.
- A coupon takes its percentage off, but never more than its cap.
- Choose the coupon with the largest saving.
- If two save the same, take the one whose code sorts first.
- If nothing saves anything, return null.
bestCoupon(basketTotal: int, coupons: list<Coupon>) → string?
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 bestCoupon(basketTotal int, coupons []Coupon) *string {
}
Worked examples
| Call | Result |
|---|---|
bestCoupon(10000, []Coupon{Coupon{Code: "TEN", PercentOff: 10, MaxOff: 5000}, Coupon{Code: "BIG", PercentOff: 50, MaxOff: 2000}}) | pStr("BIG") |
bestCoupon(10000, []Coupon{Coupon{Code: "ZED", PercentOff: 20, MaxOff: 9000}, Coupon{Code: "ACE", PercentOff: 20, MaxOff: 9000}}) | pStr("ACE") |
bestCoupon(100, []Coupon{Coupon{Code: "TINY", PercentOff: 0, MaxOff: 500}}) | nil |
bestCoupon(10000, []Coupon{}) | nil |
Hint
Work out each saving first, then compare. Integer division truncates, which is in the shop’s favour.
Reference solution in Go
func bestCoupon(basketTotal int, coupons []Coupon) *string {
var bestCode *string
bestSave := 0
for i := range coupons {
c := coupons[i]
save := basketTotal * c.PercentOff / 100
if c.MaxOff < save {
save = c.MaxOff
}
if save <= 0 {
continue
}
if save > bestSave || (save == bestSave && bestCode != nil && c.Code < *bestCode) {
bestSave = save
code := c.Code
bestCode = &code
}
}
return bestCode
}