1+ use std:: collections:: HashMap ;
2+
3+ /// @number 1357
4+ /// @title Apply Discount Every n Orders
5+ /// @url https://leetcode.com/problems/apply-discount-every-n-orders
6+ /// @difficulty medium
7+ //There is a sale in a supermarket, there will be a discount every n customer.
8+ //There are some products in the supermarket where the id of the i-th product is
9+ // products[i] and the price per unit of this product is prices[i].
10+ //The system will count the number of customers and when the n-th customer arriv
11+ //e he/she will have a discount on the bill. (i.e if the cost is x the new cost is
12+ // x - (discount * x) / 100). Then the system will start counting customers again.
13+ //
14+ //The customer orders a certain amount of each product where product[i] is the i
15+ //d of the i-th product the customer ordered and amount[i] is the number of units
16+ //the customer ordered of that product.
17+ //
18+ // Implement the Cashier class:
19+ //
20+ //
21+ // Cashier(int n, int discount, int[] products, int[] prices) Initializes the ob
22+ //ject with n, the discount, the products and their prices.
23+ // double getBill(int[] product, int[] amount) returns the value of the bill and
24+ // apply the discount if needed. Answers within 10^-5 of the actual value will be
25+ //accepted as correct.
26+ //
27+ //
28+ //
29+ // Example 1:
30+ //
31+ //
32+ //Input
33+ //["Cashier","getBill","getBill","getBill","getBill","getBill","getBill","getBil
34+ //l"]
35+ //[[3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,100]],[[1,2],[1,2]],[[3,7],[10
36+ //,10]],[[1,2,3,4,5,6,7],[1,1,1,1,1,1,1]],[[4],[10]],[[7,3],[10,10]],[[7,5,3,1,6,4
37+ //,2],[10,10,10,9,9,9,7]],[[2,3,5],[5,3,2]]]
38+ //Output
39+ //[null,500.0,4000.0,800.0,4000.0,4000.0,7350.0,2500.0]
40+ //Explanation
41+ //Cashier cashier = new Cashier(3,50,[1,2,3,4,5,6,7],[100,200,300,400,300,200,10
42+ //0]);
43+ //cashier.getBill([1,2],[1,2]); // return 500.0, bill = 1
44+ // * 100 + 2 * 200 = 500.
45+ //cashier.getBill([3,7],[10,10]); // return 4000.0
46+ //cashier.getBill([1,2,3,4,5,6,7],[1,1,1,1,1,1,1]); // return 800.0, The bill
47+ // was 1600.0 but as this is the third customer, he has a discount of 50% which me
48+ //ans his bill is only 1600 - 1600 * (50 / 100) = 800.
49+ //cashier.getBill([4],[10]); // return 4000.0
50+ //cashier.getBill([7,3],[10,10]); // return 4000.0
51+ //cashier.getBill([7,5,3,1,6,4,2],[10,10,10,9,9,9,7]); // return 7350.0, Bill wa
52+ //s 14700.0 but as the system counted three more customers, he will have a 50% dis
53+ //count and the bill becomes 7350.0
54+ //cashier.getBill([2,3,5],[5,3,2]); // return 2500.0
55+ //
56+ //
57+ //
58+ // Constraints:
59+ //
60+ //
61+ // 1 <= n <= 10^4
62+ // 0 <= discount <= 100
63+ // 1 <= products.length <= 200
64+ // 1 <= products[i] <= 200
65+ // There are not repeated elements in the array products.
66+ // prices.length == products.length
67+ // 1 <= prices[i] <= 1000
68+ // 1 <= product.length <= products.length
69+ // product[i] exists in products.
70+ // amount.length == product.length
71+ // 1 <= amount[i] <= 1000
72+ // At most 1000 calls will be made to getBill.
73+ // Answers within 10^-5 of the actual value will be accepted as correct.
74+ // Related Topics Design
75+ // 👍 48 👎 62
76+
77+
78+ //leetcode submit region begin(Prohibit modification and deletion)
79+ struct Cashier {
80+ discount_position : i32 ,
81+ counter : i32 ,
82+ discount_rate : f64 ,
83+ product_prices : std:: collections:: HashMap < i32 , i32 > ,
84+ }
85+
86+
87+ /**
88+ * `&self` means the method takes an immutable reference.
89+ * If you need a mutable reference, change it to `&mut self` instead.
90+ */
91+ impl Cashier {
92+ fn new ( n : i32 , discount : i32 , products : Vec < i32 > , prices : Vec < i32 > ) -> Self {
93+ let map = products. into_iter ( ) . zip ( prices. into_iter ( ) ) . collect ( ) ;
94+ Self {
95+ discount_position : n,
96+ counter : 0 ,
97+ discount_rate : discount as f64 / 100.0 ,
98+ product_prices : map,
99+ }
100+ }
101+
102+ fn get_bill ( & mut self , product : Vec < i32 > , amount : Vec < i32 > ) -> f64 {
103+ self . counter += 1 ;
104+
105+ let x: f64 = product. iter ( ) . zip ( amount. iter ( ) ) . map ( |( product_id, amount) | {
106+ let price = * self . product_prices . get ( product_id) . unwrap ( ) ;
107+
108+ price as f64 * * amount as f64
109+ } ) . sum ( ) ;
110+ if self . counter == self . discount_position {
111+ self . counter = 0 ;
112+ x * ( 1.0 - self . discount_rate )
113+ } else {
114+ x
115+ }
116+ }
117+ }
118+
119+ /**
120+ * Your Cashier object will be instantiated and called as such:
121+ * let obj = Cashier::new(n, discount, products, prices);
122+ * let ret_1: f64 = obj.get_bill(product, amount);
123+ */
124+ //leetcode submit region end(Prohibit modification and deletion)
125+ #[ cfg( test) ]
126+ mod test {
127+ use crate :: apply_discount_every_n_orders:: Cashier ;
128+
129+ #[ test]
130+ fn test1 ( ) {
131+ let mut cashier = Cashier :: new ( 3 , 50 , vec ! [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] , vec ! [ 100 , 200 , 300 , 400 , 300 , 200 , 100 ] ) ;
132+
133+ assert_eq ! ( 500.0 , cashier. get_bill( vec![ 1 , 2 ] , vec![ 1 , 2 ] ) ) ;
134+ assert_eq ! ( 4000.0 , cashier. get_bill( vec![ 3 , 7 ] , vec![ 10 , 10 ] ) ) ;
135+ assert_eq ! ( 800.0 , cashier. get_bill( vec![ 1 , 2 , 3 , 4 , 5 , 6 , 7 ] , vec![ 1 , 1 , 1 , 1 , 1 , 1 , 1 ] ) ) ;
136+
137+ assert_eq ! ( 4000.0 , cashier. get_bill( vec![ 4 ] , vec![ 10 ] ) ) ;
138+ assert_eq ! ( 4000.0 , cashier. get_bill( vec![ 7 , 3 ] , vec![ 10 , 10 ] ) ) ;
139+ assert_eq ! ( 7350.0 , cashier. get_bill( vec![ 7 , 5 , 3 , 1 , 6 , 4 , 2 ] , vec![ 10 , 10 , 10 , 9 , 9 , 9 , 7 ] ) ) ;
140+ }
141+ }
0 commit comments