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?
C++ 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
std::optional<std::string> bestCoupon(int basketTotal, std::vector<Coupon> coupons) {
}
Worked examples
| Call | Result |
|---|---|
bestCoupon(10000, std::vector<Coupon>{Coupon{std::string("TEN"), 10, 5000}, Coupon{std::string("BIG"), 50, 2000}}) | std::optional<std::string>(std::string("BIG")) |
bestCoupon(10000, std::vector<Coupon>{Coupon{std::string("ZED"), 20, 9000}, Coupon{std::string("ACE"), 20, 9000}}) | std::optional<std::string>(std::string("ACE")) |
bestCoupon(100, std::vector<Coupon>{Coupon{std::string("TINY"), 0, 500}}) | std::nullopt |
bestCoupon(10000, std::vector<Coupon>{}) | std::nullopt |
Hint
Work out each saving first, then compare. Integer division truncates, which is in the shop’s favour.
Reference solution in C++
std::optional<std::string> bestCoupon(int basketTotal, std::vector<Coupon> coupons) {
std::optional<string> bestCode;
int bestSave = 0;
for (const auto& c : coupons) {
int save = std::min(basketTotal * c.percentOff / 100, c.maxOff);
if (save <= 0) continue;
if (save > bestSave || (save == bestSave && bestCode.has_value() && c.code < *bestCode)) {
bestSave = save;
bestCode = c.code;
}
}
return bestCode;
}