Problem · String

Email Subscription Scheduler

Learn this problem
MediumStripe logoStripeINTERNFULLTIMEONSITE INTERVIEW
See Stripe hiring insights

Problem statement

You are given subscription records for a group of users and a schedule of lifecycle emails. Produce the email timeline in chronological order.

Each entry in users is formatted as "name,plan,begin_day,duration". The subscription expires on begin_day + duration.

Each entry in schedule is formatted as "key,title":

  • start sends the email on begin_day.
  • A negative integer such as -15 sends the email that many days before expiry.
  • end sends the email on the expiry day.

Part 1: Scheduled emails

Generate all scheduled emails for every user.

Part 2: Plan changes

Each plan-change record in changes is formatted as "name,change_day,plan,new_plan". Emit a Changed email on change_day. Scheduled emails after that day use the new plan; the expiry day does not change.

Part 3: Renewals

Each renewal record is formatted as "name,change_day,extension,days". Emit a Renewed email on change_day, extend the user’s expiry by days, and schedule the remaining lifecycle emails from the new expiry.

Return one line per email in the format "day: [title] Subscription for name (plan)", ordered by day. When several scheduled emails share a day, preserve their order in schedule. The supplied test data does not place a change and a scheduled email on the same day.

Function

sendSubscriptionEmails(users: String[], schedule: String[], changes: String[]) → String[]

Examples

Example 1

users = ["A,X,0,30", "B,Y,1,15"]schedule = ["start,Welcome", "-15,Upcoming expiration", "end,Expired"]changes = []return = ["0: [Welcome] Subscription for A (X)", "1: [Welcome] Subscription for B (Y)", "1: [Upcoming expiration] Subscription for B (Y)", "15: [Upcoming expiration] Subscription for A (X)", "16: [Expired] Subscription for B (Y)", "30: [Expired] Subscription for A (X)"]

This is Part 1 from the source: B’s welcome and 15-day reminder both occur on day 1, while A’s reminder occurs on day 15.

Example 2

users = ["A,X,0,30", "B,Y,1,15"]schedule = ["start,Welcome", "-15,Upcoming expiration", "end,Expired"]changes = ["A,5,plan,Y"]return = ["0: [Welcome] Subscription for A (X)", "1: [Welcome] Subscription for B (Y)", "1: [Upcoming expiration] Subscription for B (Y)", "5: [Changed] Subscription for A (Y)", "15: [Upcoming expiration] Subscription for A (Y)", "16: [Expired] Subscription for B (Y)", "30: [Expired] Subscription for A (Y)"]

This is the source’s Part 2 timeline: A changes from X to Y on day 5, so A’s later reminder and expiry use Y.

Example 3

users = ["A,X,0,30", "B,Y,1,15"]schedule = ["start,Welcome", "-15,Upcoming expiration", "end,Expired"]changes = ["B,3,extension,15", "A,5,plan,Y"]return = ["0: [Welcome] Subscription for A (X)", "1: [Welcome] Subscription for B (Y)", "1: [Upcoming expiration] Subscription for B (Y)", "3: [Renewed] Subscription for B (Y)", "5: [Changed] Subscription for A (Y)", "15: [Upcoming expiration] Subscription for A (Y)", "16: [Upcoming expiration] Subscription for B (Y)", "30: [Expired] Subscription for A (Y)", "31: [Expired] Subscription for B (Y)"]

This is the source’s Part 3 timeline. B’s original expiry is day 16; extending it by 15 days moves it to day 31, so the new 15-day reminder is day 16.

Constraints

  • 1 <= users.length <= 100.
  • User names are unique, and every referenced change names an existing user.
  • 0 <= begin_day <= 10^6 and 15 <= duration <= 10^6.
  • schedule contains the source-backed start, -15, and end entries, with unique keys.
  • A user has at most one plan change and at most one renewal; change days are strictly between that user’s begin and expiry days.
  • No change day coincides with one of that user’s scheduled-email days.
  • The callable signature, CSV-style record encoding, bounds, and deterministic tie handling are FastPrep practice scaffolding; the interview report did not specify them.

More Stripe problems

drafts saved locally
public String[] sendSubscriptionEmails(String[] users, String[] schedule, String[] changes) {
  // write your code here
}
users["A,X,0,30", "B,Y,1,15"]
schedule["start,Welcome", "-15,Upcoming expiration", "end,Expired"]
changes[]
expected["0: Welcome Subscription for A (X)", "1: Welcome Subscription for B (Y)", "1: Upcoming expiration Subscription for B (Y)", "15: Upcoming expiration Subscription for A (X)", "16: Expired Subscription for B (Y)", "30: Expired Subscription for A (X)"]
checking account