Problem · Design

Workspace Credit Ledger

Learn this problem
HardAirbnb logoAirbnbFULLTIMEOA

Problem statement

Process a timestamped sequence of operations for a workspace credit ledger. The ledger starts empty, timestamps are nondecreasing integer milliseconds, and operations at the same timestamp keep their input order.

Before each external operation at timestamp t, post every rebate due at or before t. Due rebates are applied in transaction creation order. Return one string result for every operation.

Operations

  • ["CREATE_WORKSPACE", t, workspaceId]: create an active workspace with zero balance and zero activity. Return true, or false if that ID is already active.
  • ["ADD_CREDITS", t, workspaceId, amount]: add a positive integer amount and return the new balance. Return the empty string when the workspace is absent.
  • ["TRANSFER_CREDITS", t, sourceId, targetId, amount]: move credits between two distinct active workspaces. Return the source balance after success. Return the empty string when either workspace is absent, the IDs are equal, or the source has insufficient credits. A successful transfer adds amount to the source workspace's activity.
  • ["TOP_WORKSPACES", t, n]: return at most n active workspaces formatted as workspaceId(activity), ordered by activity descending and then workspace ID ascending, joined by commas. Activity is the sum of credits successfully sent and successfully consumed.
  • ["CONSUME_CREDITS", t, workspaceId, amount]: deduct a positive integer amount. Return the next global identifier transactionK on success, or the empty string when the workspace is absent or its balance is insufficient. A successful consumption adds amount to activity and schedules a rebate of floor(amount * 2 / 100) credits exactly 86,400,000 milliseconds later. Only successful consumptions consume transaction identifiers.
  • ["GET_REBATE_STATUS", t, transactionId]: return PENDING before that transaction's rebate posts, RECEIVED afterward, or the empty string for an unknown transaction.
  • ["MERGE_WORKSPACES", t, survivorId, absorbedId]: merge two distinct active workspaces into survivorId. Return true on success and false otherwise. The survivor receives the absorbed workspace's current balance and activity. Transactions and pending rebates are reassigned to the survivor, and the absorbed workspace becomes inactive.
  • ["GET_BALANCE", t, workspaceId, timeAt]: when workspaceId is active at timestamp t, return its most recent balance at or before timeAt; otherwise return the empty string. Also return the empty string when timeAt is before the workspace's creation. A survivor keeps its own pre-merge history, and its combined balance begins at the merge timestamp.

All failed mutations leave the ledger unchanged. Numeric results are returned as decimal strings.

Function

processWorkspaceCreditOperations(operations: String[][]) → String[]

Examples

Example 1

operations = [["CREATE_WORKSPACE","1","alpha"],["CREATE_WORKSPACE","2","beta"],["ADD_CREDITS","3","alpha","1000"],["TRANSFER_CREDITS","4","alpha","beta","250"],["TOP_WORKSPACES","5","2"]]return = ["true","true","1000","750","alpha(250),beta(0)"]

The transfer leaves alpha with 750 credits and records 250 activity for the sender. Receiving credits does not increase beta's activity.

Example 2

operations = [["CREATE_WORKSPACE","0","a"],["ADD_CREDITS","1","a","1000"],["CONSUME_CREDITS","10","a","250"],["GET_REBATE_STATUS","86400009","transaction1"],["GET_REBATE_STATUS","86400010","transaction1"],["GET_BALANCE","86400010","a","86400010"]]return = ["true","1000","transaction1","PENDING","RECEIVED","755"]

Consuming 250 credits leaves 750 and schedules a rebate of 5. The rebate is pending one millisecond before its due time and posts before the operation exactly at the due time.

Example 3

operations = [["CREATE_WORKSPACE","1","x"],["CREATE_WORKSPACE","2","y"],["ADD_CREDITS","3","x","100"],["ADD_CREDITS","4","y","200"],["CONSUME_CREDITS","5","y","50"],["MERGE_WORKSPACES","6","x","y"],["GET_BALANCE","7","x","4"],["GET_BALANCE","8","x","6"],["GET_REBATE_STATUS","86400005","transaction1"],["GET_BALANCE","86400005","x","86400005"],["GET_BALANCE","86400006","y","5"]]return = ["true","true","100","200","transaction1","true","100","250","RECEIVED","251",""]

Before the merge, x's own balance at timestamp 4 is 100. The merge records the combined balance 250 at timestamp 6. The pending rebate from y follows the survivor and raises x's balance to 251; querying inactive y returns the empty string.

Constraints

  • 1 <= operations.length <= 2000.
  • Every timestamp is a nonnegative integer that fits a signed 64-bit integer, timestamps are nondecreasing, and every derived rebate due time also fits a signed 64-bit integer.
  • Every operation has exactly one valid shape listed above.
  • Workspace IDs are non-empty printable ASCII strings without commas or parentheses.
  • Every credit amount is a positive integer, and all balances and activity totals fit signed 64-bit integers.
  • 1 <= n <= 10^5 for TOP_WORKSPACES.
  • 0 <= timeAt <= t for GET_BALANCE.

More Airbnb problems

drafts saved locally
public String[] processWorkspaceCreditOperations(String[][] operations) {
    // Write your code here.
}
operations[["CREATE_WORKSPACE","1","alpha"],["CREATE_WORKSPACE","2","beta"],["ADD_CREDITS","3","alpha","1000"],["TRANSFER_CREDITS","4","alpha","beta","250"],["TOP_WORKSPACES","5","2"]]
expected["true", "true", "1000", "750", "alpha(250)", "beta(0)"]
checking account