Design an Uber Eats pricing calculator for food orders. Each food item has a price based on its size, and customers may add toppings. The final price can be affected by BOGO offers, surge pricing, coupon discounts, and an extra Uber One member discount.
All prices are represented in cents. Return the final payable amount as an integer number of cents.
Pricing Rules
- Each ordered item has one food id, one size, and zero or more toppings.
- The item price is calculated as
food size price + sum of topping prices.
- BOGO is applied before surge, coupons, and Uber One discount.
- For every BOGO food id, if there are
k ordered items with that food id, exactly k / 2 items are free using floor division.
- If several items of the same BOGO food id have different prices, the cheapest eligible items are made free first.
- Surge is applied after BOGO using
amount + amount * surgePercent / 100.
- Coupon discount is applied after surge using
min(amount * discountPercent / 100, maxDiscount).
- Uber One members get an additional
5% discount after coupon discount.
- All percentage calculations use floor division.
- The final amount cannot be negative.
Method Signatures
Constructor
UberEatsPricingCalculator(List<String> foodItems, List<String> toppingPrices, List<String> bogoFoodIds, List<String> coupons)
foodItems: list of food definitions.
- Each food definition is in the format
"foodId,smallPrice,mediumPrice,largePrice".
toppingPrices: list of topping definitions.
- Each topping definition is in the format
"toppingId,price".
bogoFoodIds: list of food ids eligible for BOGO.
coupons: list of coupon definitions.
- Each coupon definition is in the format
"couponCode,discountPercent,maxDiscount".
Calculate Total
int calculateTotal(List<String> orderItems, String couponCode, boolean isUberOneMember, int surgePercent)
- The final payable amount is guaranteed to fit in a 32-bit signed integer.
orderItems: list of ordered items.
- Each ordered item is in the format
"foodId,size,toppingId|toppingId|...".
- If an item has no toppings, use "NONE" as the toppings value.
couponCode: coupon to apply.
- If no coupon is used, pass
"NONE".
isUberOneMember: whether the customer has Uber One membership.
surgePercent: surge percentage applied to the order after BOGO.
Constraints
0 ≤ maxDiscount ≤ 1,000,000 cents.
1 ≤ foodItems.size() ≤ 1000
0 ≤ toppingPrices.size() ≤ 1000
0 ≤ bogoFoodIds.size() ≤ 1000
0 ≤ coupons.size() ≤ 1000
1 ≤ orderItems.size() ≤ 10,000
0 ≤ surgePercent ≤ 500
0 ≤ discountPercent ≤ 100
0 ≤ price ≤ 1,000,000
size is one of "small", "medium", or "large".
- All food ids, topping ids, and coupon codes are case-sensitive.
- All food ids are unique.
- All topping ids are unique.
- All coupon codes are unique.
- No food id, topping id, or coupon code is equal to
"NONE".
- The same topping id will not appear more than once for a single ordered item.
- All ids used in
orderItems are valid.
- All food ids in
bogoFoodIds are valid food ids from foodItems.
- If
couponCode is not "NONE", it is guaranteed to exist in coupons.
- Food ids, topping ids, and coupon codes do not contain comma
, or pipe | characters.
Examples
Example 1
UberEatsPricingCalculator(foodItems = ["burger,500,700,900", "pizza,800,1000,1200"], toppingPrices = ["cheese,100", "olive,150"], bogoFoodIds = ["burger"], coupons = ["SAVE10,10,300"])
calculateTotal(orderItems = ["burger,medium,cheese", "burger,large,NONE", "pizza,small,olive"], couponCode = "SAVE10", isUberOneMember = true, surgePercent = 20)
Output: 1899
Explanation: Burger medium with cheese costs 800, burger large costs 900, and pizza small with olive costs 950. Since burger has BOGO, the cheaper burger item worth 800 becomes free. Amount after BOGO is 1850. After 20% surge, amount becomes 2220. Coupon SAVE10 gives 222 discount. Amount becomes 1998. Uber One gives additional 5% discount, which is 99. Final amount is 1899.
Example 2
UberEatsPricingCalculator(foodItems = ["wrap,300,450,600", "fries,200,300,400"], toppingPrices = ["sauce,50"], bogoFoodIds = ["fries"], coupons = ["FLAT20,20,100"])
calculateTotal(orderItems = ["fries,large,NONE", "fries,small,sauce", "wrap,medium,NONE"], couponCode = "NONE", isUberOneMember = false, surgePercent = 0)
Output: 850
Explanation: Fries large costs 400, fries small with sauce costs 250, and wrap medium costs 450. Since fries has BOGO, the cheaper fries item worth 250 becomes free. No surge, coupon, or Uber One discount is applied. Final amount is 850.
Example 3
UberEatsPricingCalculator(foodItems = ["rice,400,550,700"], toppingPrices = ["egg,80", "paneer,120"], bogoFoodIds = [], coupons = ["MEAL15,15,200"])
calculateTotal(orderItems = ["rice,large,egg|paneer", "rice,small,NONE"], couponCode = "MEAL15", isUberOneMember = false, surgePercent = 10)
Output: 1230
Explanation: Rice large with egg and paneer costs 900, and rice small costs 400. Amount before discounts is 1300. After 10% surge, amount becomes 1430. Coupon discount is 214, but max discount is 200, so 200 is applied. Final amount is 1230.