Credit Accounts with Scheduled Transfers
Problem statement
Maintain credit accounts through a timestamped sequence of operations. Support account creation, credit additions, immediate transfers, balance ranking, scheduled transfers, cancellation, account merging and historical balance queries.
Operation ordering
Process queries in order. Each row contains an operation name, its timestamp and the arguments below. Before every external operation at timestamp t, process all pending transfers whose due time is at most t, ordered by due time and then scheduling order. Record a scheduled transfer's balance changes at its due time, even when the next external operation occurs later.
Return one string per external query. Use true or false for booleans, base-10 strings for numbers and an empty string for an unsuccessful numeric or identifier result.
Accounts and immediate transfers
["CREATE_ACCOUNT", t, id]: create an account with balance zero and returntrue. Returnfalseif that identifier has ever been created, including an identifier removed by a merge.["ADD_CREDIT", t, id, amount]: add positive credits to an active account and return its new balance. Return the empty string if the account is inactive or absent.["TRANSFER", t, source, target, amount]: transfer positive credits between distinct active accounts. Return the source balance after success. Return the empty string if either account is absent or inactive, the identifiers are equal or funds are insufficient.["TOP_K", t, k]: rank active accounts by current credit balance descending, breaking ties by identifier ascending. Return at mostkentries formattedid(balance), joined by commas without spaces. Return the empty string if no active accounts exist.
Scheduled transfers
["SCHEDULE_TRANSFER", t, source, target, amount, delay]: if the endpoints are distinct active accounts, schedule a transfer fort + delayand return the next global identifiertransferK, starting withtransfer1. An invalid request returns the empty string and consumes no identifier.- Scheduling does not reserve or move credits. When the transfer becomes due, execute it only if both endpoints remain active and the source has sufficient credits. Otherwise skip it permanently. A processed transfer is no longer pending whether it succeeds or fails.
["CANCEL_TRANSFER", t, source, transferId]: returntrueand cancel the transfer only when it is pending and belongs to that active source account. Returnfalseotherwise. Due transfers are processed before this cancellation, including transfers due exactly att.
Merge and balance history
["MERGE_ACCOUNTS", t, survivor, absorbed]: first process due transfers as usual. Returnfalseif the identifiers are equal or either account is not active. Otherwise add the absorbed balance to the survivor, deactivate the absorbed account, cancel every remaining pending transfer having the absorbed account as either endpoint and returntrue. Pending transfers do not reserve funds, so cancellation does not refund credits.["GET_BALANCE", t, id, timeAt]: return that identifier's balance immediately after all activity attimeAt, or after its latest earlier activity if nothing occurred exactly then. Return the empty string if the account had not been created or was already deactivated at that historical time. A deactivated identifier remains queryable for its own pre-merge history.- The survivor keeps its own pre-merge history. Its combined balance starts at the merge timestamp. The absorbed identifier stops existing at the merge timestamp.
For this exercise, assume timestamps are strictly increasing, identifiers are never reused, transfers use positive integer credits without fees, failed scheduled transfers are not retried, and historical balances follow the identifier-specific rules above.
Function
processCreditAccounts(queries: String[][]) → String[]Examples
Example 1
queries = [["CREATE_ACCOUNT","1","a"],["CREATE_ACCOUNT","2","b"],["ADD_CREDIT","3","a","100"],["ADD_CREDIT","4","b","30"],["TRANSFER","5","a","b","40"],["TOP_K","6","2"]]return = ["true","true","100","30","60","b(70),a(60)"]The immediate transfer leaves a with 60 and b with 70. Ranking uses the current balances.
Example 2
queries = [["CREATE_ACCOUNT","1","a"],["CREATE_ACCOUNT","2","b"],["CREATE_ACCOUNT","3","c"],["ADD_CREDIT","4","b","100"],["SCHEDULE_TRANSFER","5","b","c","30","5"],["SCHEDULE_TRANSFER","6","b","c","20","10"],["MERGE_ACCOUNTS","10","a","b"],["GET_BALANCE","11","c","10"],["GET_BALANCE","12","b","9"],["GET_BALANCE","13","b","10"],["GET_BALANCE","16","a","16"]]return = ["true","true","true","100","transfer1","transfer2","true","30","100","","70"]The first scheduled transfer executes at timestamp 10 before the merge, leaving b with 70 and c with 30. The merge moves 70 into a and cancels the second transfer. Account b remains queryable at timestamp 9 but no longer exists at timestamp 10.
Example 3
queries = [["CREATE_ACCOUNT","1","a"],["CREATE_ACCOUNT","2","b"],["ADD_CREDIT","3","a","50"],["SCHEDULE_TRANSFER","4","a","b","40","6"],["SCHEDULE_TRANSFER","5","a","b","30","5"],["CANCEL_TRANSFER","10","a","transfer1"],["TOP_K","11","2"],["GET_BALANCE","12","a","10"]]return = ["true","true","50","transfer1","transfer2","false","b(40),a(10)","10"]Both scheduled transfers are due at timestamp 10. The earlier scheduled transfer succeeds first; the second lacks funds and is skipped. Cancellation occurs afterward and returns false.
Constraints
1 <= queries.length <= 500.- External timestamps are strictly increasing integers from
0through10^9. - Every query has a valid operation shape. Amounts and delays are positive integers at most
10^9. - Account identifiers contain only ASCII letters, digits and underscores, with length from
1through32. - Every balance and derived due time fits in a signed 64-bit integer.
- For
TOP_K,1 <= k <= 500. ForGET_BALANCE,0 <= timeAt <= t.