Generate Account Email Notifications
Company: Stripe
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Technical Screen
Quick Answer: This question evaluates the ability to implement date-based rule evaluation, efficient filtering and ordering over large account lists, and template rendering with attention to algorithmic efficiency and correctness.
Constraints
- 0 <= len(accounts) <= 200000
- 0 <= len(rules) <= 200000
- 0 <= current_day, created_day, expires_day, offset_days <= 10^9
- For every account, created_day <= expires_day
- Each rule trigger is one of: `on_create`, `days_before_expiration`, `after_expiration`
- The total number of generated notifications will not exceed 200000
Examples
Input: (10, [{"account_id": "A1", "created_day": 10, "expires_day": 30}, {"account_id": "A2", "created_day": 2, "expires_day": 13}, {"account_id": "A3", "created_day": 1, "expires_day": 8}], [{"name": "welcome", "trigger": "on_create", "template": "Welcome!"}, {"name": "three_day_reminder", "trigger": "days_before_expiration", "offset_days": 3, "template": "Your account expires in 3 days."}, {"name": "expired", "trigger": "after_expiration", "template": "Your account has expired."}])
Expected Output: ["A1 welcome Welcome!", "A2 three_day_reminder Your account expires in 3 days.", "A3 expired Your account has expired."]
Explanation: A1 was created today, A2 expires in 3 days, and A3 is already expired.
Input: (5, [], [{"name": "welcome", "trigger": "on_create", "template": "Welcome!"}])
Expected Output: []
Explanation: There are no accounts, so no notifications are generated.
Input: (20, [{"account_id": "B1", "created_day": 20, "expires_day": 22}, {"account_id": "B2", "created_day": 10, "expires_day": 19}], [{"name": "two_day", "trigger": "days_before_expiration", "offset_days": 2, "template": "Account expires soon."}, {"name": "welcome", "trigger": "on_create", "template": "Welcome aboard."}, {"name": "expired", "trigger": "after_expiration", "template": "Account expired."}, {"name": "final_notice", "trigger": "days_before_expiration", "offset_days": 2, "template": "2 days left."}])
Expected Output: ["B1 two_day Account expires soon.", "B1 welcome Welcome aboard.", "B1 final_notice 2 days left.", "B2 expired Account expired."]
Explanation: B1 matches three rules. They must be emitted in the same order as the rule list: rule 0, then 1, then 3. B2 only matches the expired rule.
Input: (7, [{"account_id": "C1", "created_day": 1, "expires_day": 7}, {"account_id": "C2", "created_day": 7, "expires_day": 7}], [{"name": "expires_today", "trigger": "days_before_expiration", "offset_days": 0, "template": "Your account expires today."}, {"name": "welcome", "trigger": "on_create", "template": "Welcome!"}, {"name": "expired", "trigger": "after_expiration", "template": "Your account has expired."}])
Expected Output: ["C1 expires_today Your account expires today.", "C2 expires_today Your account expires today.", "C2 welcome Welcome!"]
Explanation: An offset of 0 means the reminder is sent on the expiration day. `after_expiration` does not trigger when `current_day == expires_day`.
Input: (12, [{"account_id": "D1", "created_day": 1, "expires_day": 20}], [{"name": "welcome", "trigger": "on_create", "template": "Welcome!"}, {"name": "two_day", "trigger": "days_before_expiration", "offset_days": 2, "template": "2 days left."}, {"name": "expired", "trigger": "after_expiration", "template": "Expired."}])
Expected Output: []
Explanation: D1 was not created today, does not expire in 2 days, and is not expired yet.
Hints
- Preprocess the rules by trigger type. For `days_before_expiration`, grouping by `offset_days` lets you find matching rules in O(1) for each account.
- You still need to preserve the original rule order. Store each rule's original index, then merge only the small set of matching rule groups for each account.