Calculate Per-User Usage Charges
Company: Stripe
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: hard
Interview Round: Take-home Project
Quick Answer: This question evaluates algorithmic data aggregation, numeric billing computations, and the ability to model proration and threshold semantics across mixed subscription and pay-as-you-go records.
Constraints
- 0 <= len(records) <= 10^5
- 0 <= input_tokens, output_tokens <= 10^9
- plan is either 'PAYG' or 'MONTHLY'
- 0 <= p <= 1 for every proration value
- If a user has MONTHLY records and is missing from prorations, assume p = 1.0
Examples
Input: ([('alice', 100, 50, 'PAYG'), ('bob', 1200, 900, 'MONTHLY'), ('bob', 100, 50, 'PAYG'), ('carol', 600, 400, 'MONTHLY'), ('carol', 200, 100, 'MONTHLY'), ('carol', 50, 25, 'PAYG')], 0.01, 0.02, 20.0, 1000, 800, {'bob': 1.0, 'carol': 0.5})
Expected Output: {'alice': 2.0, 'bob': 26.0, 'carol': 16.0}
Explanation: alice has only PAYG usage: 100*0.01 + 50*0.02 = 2. bob pays full monthly fee 20, plus excess monthly usage (200 input and 100 output) for 4 more, plus PAYG charges of 2, totaling 26. carol has p=0.5, so monthly fee is 10 and thresholds are 500 input and 400 output; her monthly excess is 300 input and 100 output, adding 5, and her PAYG usage adds 1, so total is 16.
Input: ([], 0.01, 0.02, 10.0, 100, 100, {})
Expected Output: {}
Explanation: No records means no users and no charges.
Input: ([('u1', 50, 50, 'MONTHLY'), ('u1', 50, 50, 'MONTHLY'), ('u1', 10, 0, 'PAYG')], 1.0, 2.0, 30.0, 100, 100, {})
Expected Output: {'u1': 40.0}
Explanation: u1 is not in prorations, so p=1.0. The two MONTHLY records exactly match the included thresholds, so only the monthly fee of 30 is charged for them. The PAYG record adds 10*1.0 = 10, for a total of 40.
Input: ([('z', 10, 10, 'MONTHLY'), ('z', 5, 5, 'PAYG')], 2.0, 3.0, 100.0, 100, 100, {'z': 0.0})
Expected Output: {'z': 75.0}
Explanation: With p=0, the monthly fee and included thresholds are both zero. So the MONTHLY usage is fully billed at PAYG rates: 10*2 + 10*3 = 50. The PAYG record adds 5*2 + 5*3 = 25, for a total of 75.
Input: ([('m', 30, 40, 'MONTHLY'), ('n', 1, 2, 'PAYG')], 1.0, 1.5, 5.0, 100, 100, {})
Expected Output: {'m': 5.0, 'n': 4.0}
Explanation: m has monthly usage below the included thresholds, so m pays only the monthly fee of 5. n has only PAYG usage: 1*1.0 + 2*1.5 = 4.
Hints
- Aggregate data by user. PAYG charges can be added immediately, but MONTHLY usage should be summed first.
- For each user with MONTHLY usage, apply the prorated fee and prorated thresholds once to that user's total MONTHLY input and output tokens.