AlgoMaster Logo
AlgoMasterDesign Discount Calculatormedium

Design Discount Calculator

medium

An online store changes promotions throughout the day: sometimes there is no offer, sometimes every cart gets a percentage off, and sometimes a coupon removes a fixed amount. Checkout should not grow a new conditional branch every time the marketing team changes the rule.

The ShoppingCart context is already implemented in the starter code. Complete only the discount strategy family:

  • DiscountStrategy defines name() and applyDiscount(price).
  • NoDiscount returns the name "none" and leaves the price unchanged.
  • PercentageDiscount receives a percentage in its constructor, returns the name "percentage", and reduces the price by that percentage.
  • FlatDiscount receives an amount in its constructor, returns the name "flat", and subtracts that amount without ever returning a negative price.

For example, a 20% strategy turns 100.0 into 80.0, while a flat 15 strategy turns it into 85.0. A flat 150 strategy floors the final price at 0.0.

The supplied cart validates strategy settings, swaps the active strategy, counts valid checkouts, and formats receipts. The tests use its public API:

  • setNoDiscount(), setPercentageDiscount(percent), and setFlatDiscount(amount) select a strategy. Invalid values leave the current strategy unchanged.
  • currentStrategy() returns "none", "percentage", or "flat".
  • checkout(price) applies the active strategy. A negative price returns -1.0 and is not counted.
  • receipt(price) returns "Original: $<price> | Final: $<final>" with two decimal places, or "INVALID" for a negative price.
  • checkoutCount() returns the number of valid checkouts performed by checkout or receipt.
Example 1:

Input:

Output:

Explanation: A new cart applies no discount, so the price is unchanged. After switching to twenty percent, the same price comes back reduced.

Example 2:

Input:

Output:

Explanation: A flat discount of 15 off 100 leaves 85, and the receipt reports the original alongside the final price.

Constraints

  • 0.0 <= percent <= 100.0
  • 0.0 <= amount <= 10000.0
  • -1.0 <= price <= 10000.0
  • At most 100 calls in total are made across all methods.

How the design is graded

needs 7/10 to pass
  • Strategy separation

    Full marks when each discount rule is its own class behind one contract and `checkout` calls it without knowing which one it holds, with the percentage and the amount stored on their strategies. Lose points heavily when `checkout` branches on the strategy name, or when the cart keeps a percent field that only one rule uses.

  • A do-nothing strategy is ordinary

    Full marks when the no-discount rule is a normal implementation returning the price unchanged, needing no special case anywhere. Lose points when the cart tests for it before applying, or when the cart cannot operate without a discount being set.

  • Structure and naming

    Full marks when a flat discount larger than the price yields exactly `0.0`, an invalid percent or negative amount is refused without changing the strategy, a negative price returns `-1.0` and `INVALID` without counting, and `receipt` agrees with `checkout`. Lose points for printing to stdout.

Passing every test is not enough on its own. A submission is accepted only when the design also clears the bar.

Hints

Loading...
CallReturns
new ShoppingCart()null
currentStrategy()"none"
receipt(100)"Original: $100.00 | Final: $100.00"
setPercentageDiscount(20)true
receipt(100)"Original: $100.00 | Final: $80.00"
checkoutCount()2

A new cart applies no discount, so the price is unchanged. After switching to twenty percent, the same price comes back reduced.

Run checks these cases. Submit also runs a larger hidden set.