Exercise: Open/Closed
This exercise puts the Open/Closed Principle into code.
Scenario
A pricing engine receives a list of ["apply", type, base, param] commands and returns one output line per command. Three discount types are supported: percent reduces the base price by a percentage, flat subtracts a fixed amount, and none leaves the price unchanged. An unrecognized type produces an error line. All prices and parameters are integers.
Commands
| Command | Behavior | Output |
|---|---|---|
["apply", "percent", base, param] | Deduct (base * param) // 100 using integer division | The resulting price as a string |
["apply", "flat", base, param] | Deduct param from base, floored at 0 | The resulting price as a string |
["apply", "none", base, param] | Return base unchanged | The resulting price as a string |
["apply", unknown, base, param] | Unrecognized type | "Unknown discount: <type>" |
6 apply percent 200 10 apply flat 200 30 apply none 200 0 apply flat 5 20 apply percent 150 25 apply mystery 100 5
180 170 200 0 113 Unknown discount: mystery
10% off 200 is 20, leaving 180. Flat 30 off 200 leaves 170. No discount leaves 200. Flat 20 off 5 would be negative, so it floors at 0. 25% of 150 is 37 (integer division), leaving 113. The type mystery is not in the registry, so it produces an error.
Your task
Create the three discount classes used by the registry below the Discount abstract class in the editor: PercentDiscount, FlatDiscount, and NoDiscount, each subclassing Discount and implementing apply. Do not modify Discount, the DISCOUNT_REGISTRY, or run_discounts.