Start learning free

LESSON 663 OF 679 · OBJECT-ORIENTED PROGRAMMING - CHALLENGES

Payment Fees

Practice O(1)

A shop takes payments by card, by PayPal and in cash. Every payment has an amount, in cents, and a total: the amount plus a processing fee. The total is worked out the same way for every payment; only the fee depends on the kind of payment. That is what an abstract class is for: it holds the shared part, says that every payment has a fee, and leaves the fee itself to each kind of payment.

Rust has no classes and no abstract classes. As in the abstract-classes lesson, a trait plays the abstract class:

  • The trait Payment declares two methods with no body, which every payment must write: fn get_amount(&self) -> i32 and fn fee(&self) -> i32.
  • It also has a default method, fn total(&self) -> i32, with a body: self.get_amount() + self.fee(). Every type that implements Payment gets it for free.
  • A trait can't hold fields, so Card, PayPal and Cash each keep their own amount. Card::new(amount), PayPal::new(amount) and Cash::new(amount) build them, and each impl Payment for ... writes get_amount and its own fee:
  • Card pays 2%: its fee is amount × 2 / 100.
  • PayPal pays 3% plus 30 cents: its fee is amount × 3 / 100 + 30.
  • Cash costs nothing: its fee is 0.

Dividing two i32s drops the fraction.

Every division rounds down: a card payment of 1999 cents has a fee of 39, not 39.98.

The starter code already has every struct, every impl block and every method header: declare the trait's two methods and the structs' fields, and write the bodies. For each test, the harness creates the payments in the order given and prints two lines: each payment's total, total(), separated by spaces, and then the sum of all the fees. It calls them through the trait Payment, never through Card, PayPal or Cash.

 

Example 1:

Input:
    Card::new(1999)
    PayPal::new(500)
    Cash::new(700)
Output:
    2038 545 700
    84
Explanation: The card's fee is 1999 × 2 / 100 = 39 (39.98 rounded down), so its total is 2038. PayPal's fee is 500 × 3 / 100 + 30 = 45, total 545. Cash has no fee: total 700. The fees add up to 39 + 45 + 0 = 84.

Example 2:

Input:
    Card::new(49)
    PayPal::new(33)
    Card::new(50)
Output:
    49 63 51
    31
Explanation: 49 × 2 / 100 is 0.98, rounded down to 0. PayPal's 33 × 3 / 100 is 0.99, rounded down to 0, plus 30. The second card's 50 × 2 / 100 is exactly 1. The fees are 0 + 30 + 1 = 31.

Example 3:

Input:
    Card::new(0)
    PayPal::new(0)
    Cash::new(0)
Output:
    0 30 0
    30
Explanation: Amounts can be 0. PayPal still adds its 30 cents.

 

Constraints:

  • Every test has between 1 and 100 payments.
  • Every amount is an integer from 0 to 106 cents.

Note:

Every fee and every total takes O(1) time.

STEP 1 OF 15
    Ctrl + Enter to check