Skip to content
BytePatterns

Best Discount Strategy at Checkout

EasyLow-Level Design#strategy-pattern#class-design~15m

Problem

A shop runs several promotions but applies only one per order. A cart is a list of (item, price, quantity) with prices in cents. Write three promotion classes that share one interface, a name and a discount(cart) method: PercentOff(pct) takes pct percent off the subtotal, rounded down; AmountOffOver(threshold, amount) takes a flat amount off when the subtotal reaches the threshold; and BuyNGetOneFree(item, n) makes every (n + 1)th unit of one item free. Then write checkout(cart, promotions), which picks the promotion with the largest discount, the first one listed on a tie, and returns its name with the total to pay. If no promotion saves anything, return "no discount" with the subtotal.

Examples

Input:  cart = [("coffee", 1200, 3), ("mug", 900, 2)], all three promotions
Output: ('buy 2 coffee get 1 free', 4200)
Why:    one free coffee saves 1200, more than 10% (540) or 800 off over 5000
Input:  cart = [("grinder", 9900, 1)], all three promotions
Output: ('10% off', 8910)
Why:    on a large order the percentage beats the flat amount
Input:  cart = [("mug", 900, 1)], only AmountOffOver(5000, 800)
Output: ('no discount', 900)
Why:    edge case, the order is below the threshold, so nothing applies

Hints

0 / 3

Stuck on the idea rather than the code? Strategy Pattern covers it.