Problempromotion aware shopping basket

Session: Sign in to solve

Solution.txt

Shopping Basket with Coupons

Problem

Design ShoppingBasket for a store that keeps products and coupons in one ordered sequence. Each product has a type and an integer price in cents, and each coupon changes the price of its specified products when the total is calculated.

Requirements

  • Preserve basket order. add appends each Product or Coupon after all existing entries, and total calculation uses that insertion order.
  • Use distinct coupon types. AllProductsPercentCoupon, NextProductPercentCoupon, and NthProductOfTypeFixedCoupon are separate Coupon implementations accepted as BasketEntry values.
  • Discount all products. AllProductsPercentCoupon reduces the current price of every product, including products before and after the coupon.
  • Discount the next product. NextProductPercentCoupon reduces the first later Product, regardless of its type and ignoring intervening coupon entries.
  • Discount the Nth product of a type. NthProductOfTypeFixedCoupon subtracts its fixed discount from the one-based Nth Product with the matching productType, ignoring coupon entries and other product types.
  • Apply every coupon. netTotalCents applies every coupon entry exactly once.
  • Apply coupons left to right. Each coupon starts from the prices produced by earlier coupons.
  • Round each percentage. After each percentage coupon, a target price becomes floor(currentPriceCents * (100 - percentOff) / 100).
  • Return the net total. netTotalCents returns the sum of all final product prices; coupon entries add no price.
  • Keep totals repeatable. netTotalCents does not mutate stored entries and starts from each product's original price, so an unchanged basket returns the same total on repeated calls.

API

SignatureReturnsBehavior
BasketEntryNot applicableMarker abstraction shared by Product and Coupon.
Product(productType: string, priceCents: integer)ProductCreates one immutable priced product of the supplied type.
CouponNot applicableAbstract basket entry implemented by each coupon type.
AllProductsPercentCoupon(percentOff: integer)AllProductsPercentCouponCreates a coupon that targets every product.
NextProductPercentCoupon(percentOff: integer)NextProductPercentCouponCreates a coupon that targets the first later product.
NthProductOfTypeFixedCoupon(productType: string, productNumber: integer, discountCents: integer)NthProductOfTypeFixedCouponCreates a coupon that targets the one-based Nth product of the supplied type.
ShoppingBasket()ShoppingBasketCreates an empty ordered basket.
add(entry: BasketEntry)voidAppends the non-null product or coupon entry.
netTotalCents()integerRe-evaluates the current sequence from original product prices and returns its discounted total.

All constructors and calls satisfy the constraints below. Behavior outside those constraints is unspecified and is not judged.

Examples

StepOperationResult
1add(Product("BOOK", 1000))Appends a book.
2add(NextProductPercentCoupon(10))Appends a 10 percent next-product coupon.
3add(Product("STATIONERY", 2000))Appends the first later Product, which the coupon targets.
4add(Product("BOOK", 3000))Appends another later Product.
5netTotalCents()5800

For the sequence Product("BOOK", 1000), NthProductOfTypeFixedCoupon("BOOK", 2, 200), AllProductsPercentCoupon(25), NextProductPercentCoupon(10), Product("BOOK", 1000), the product prices become 750 and 540 cents, so netTotalCents() returns 1290.

Constraints

  • A basket has 1 to 100 entries and at least one product when netTotalCents is called.
  • productType is nonempty, has at most 32 characters, and uses exact string equality.
  • 1 <= priceCents <= 1,000,000,000.
  • 1 <= percentOff <= 100.
  • productNumber names an existing matching product position.
  • A next-product coupon always has a later product.
  • A fixed discount never exceeds its target's current price when applied.
  • Every intermediate product price and final total fits a signed 64-bit integer.
  • A testcase calls netTotalCents at most 100 times.

Notes

Type-specific product positions count only Product entries with the coupon's exact productType. Calls are sequential; concurrency is outside the contract.

PRIVATE WORKSPACE

Checking your session…

The statement is public. The editor, editorial, submissions, and saved work are private.