FastPrepBanking System with Pending Transfer Acceptance

Banking System with Pending Transfer Acceptance

Circle logoCircle● MediumFULLTIMEPHONE SCREEN
Learn

Problem statement

Implement a simplified banking system. The assessment is cumulative: after unlocking a new level, every operation from the current and previous levels remains available.

Query and Output Rules

  • Each query calls exactly one operation and includes a stringified millisecond timestamp.
  • Timestamps are unique, lie between 1 and 10^9, and appear in strictly increasing order.
  • Return one string result for every query, in input order.
  • Return the empty string when an operation has no successful scalar result, exactly as specified below.

Multipart Series

Level 1: Accounts and Payments

The banking system should support creating new accounts, depositing money, and withdrawing or paying money from accounts.

  • CREATE_ACCOUNT <timestamp> <accountId> creates a new account with the given accountId if it does not already exist. Return "true" if the account is created and "false" if it already exists.
  • DEPOSIT <timestamp> <accountId> <amount> deposits amount into the account. Return the account balance after processing the query, or the empty string if the account does not exist.
  • PAY <timestamp> <accountId> <amount> withdraws amount from the account. Return the account balance after processing the query. Return the empty string if the account does not exist or has insufficient funds.

Level 2: Activity Ranking

The banking system should support ranking accounts by the total value of their transactions.

  • TOP_ACTIVITY <timestamp> <n> returns the top n accounts with the highest total transaction value, sorted by total value descending and then by accountId alphabetically ascending.
  • Return one string in the format "<accountId1>(<transactionsValue1>), ..., <accountIdN>(<transactionsValueN>)".
  • Total transaction value is the sum of every processed amount for an account, regardless of how it changes the balance: deposits, payments, and each side of a successfully accepted transfer count.
  • If fewer than n accounts exist, return all active accounts in the same format.

Level 3: Pending Transfer Acceptance

The banking system should allow transfers to be scheduled and their status to be resolved by the target account.

  • TRANSFER <timestamp> <sourceAccountId> <targetAccountId> <amount> initiates a transfer. Withdraw amount from the source immediately and hold it until the target accepts the transfer or it expires. Refund the held money to the source when it expires.
  • Return the empty string when the source equals the target, either account is absent, or the source has insufficient funds.
  • A transfer expires after 24 * 60 * 60 * 1000 = 86400000 milliseconds. It expires at the beginning of the next millisecond after that period, so acceptance at the exact expiration timestamp is still valid.
  • A valid transfer returns the next global ID: "transfer1", "transfer2", and so on. Failed transfers do not consume an ID.
  • The source and target transaction histories are updated only after acceptance. A successfully accepted transfer contributes its amount to the total transaction value of both accounts.
  • ACCEPT_TRANSFER <timestamp> <accountId> <transferId> accepts a pending transfer. Return "true" on success. Return "false" if the transfer does not exist, was already accepted, expired, or accountId is not its target.

Function

bankingAcceptedTransfersLevel3(queries: String[][]) → String[]

Examples

Example 1

queries = [["CREATE_ACCOUNT","1","account1"],["CREATE_ACCOUNT","2","account1"],["CREATE_ACCOUNT","3","account2"],["DEPOSIT","4","non-existing","2700"],["DEPOSIT","5","account1","2700"],["PAY","6","non-existing","2700"],["PAY","7","account1","2701"],["PAY","8","account1","200"]]return = ["true","false","true","","2700","","","2500"]

The duplicate account creation fails. Missing-account operations and an overdraw return empty strings. The final payment succeeds and leaves account1 with 2500.

Example 2

queries = [["CREATE_ACCOUNT","1","account1"],["CREATE_ACCOUNT","2","account2"],["CREATE_ACCOUNT","3","account3"],["DEPOSIT","4","account1","2000"],["DEPOSIT","5","account2","3000"],["DEPOSIT","6","account3","4000"],["TOP_ACTIVITY","7","3"],["PAY","8","account1","1500"],["PAY","9","account2","250"],["DEPOSIT","10","account3","250"],["TOP_ACTIVITY","11","3"]]return = ["true","true","true","2000","3000","4000","account3(4000), account2(3000), account1(2000)","500","2750","4250","account3(4250), account1(3500), account2(3250)"]

The first ranking follows the three deposits. Payments count toward total activity even though they reduce balances, so the second ranking uses totals 4250, 3500, and 3250.

Example 3

queries = [["CREATE_ACCOUNT","1","account1"],["CREATE_ACCOUNT","2","account2"],["DEPOSIT","3","account1","2000"],["DEPOSIT","4","account2","3000"],["TRANSFER","5","account1","account2","5000"],["TRANSFER","16","account1","account2","1000"],["ACCEPT_TRANSFER","20","account1","transfer1"],["ACCEPT_TRANSFER","21","non-existing","transfer1"],["ACCEPT_TRANSFER","22","account1","transfer2"],["ACCEPT_TRANSFER","25","account2","transfer1"],["ACCEPT_TRANSFER","30","account2","transfer1"],["TRANSFER","40","account1","account2","1000"],["ACCEPT_TRANSFER","86400045","account2","transfer2"],["TRANSFER","86400050","account1","account1","1000"]]return = ["true","true","2000","3000","","transfer1","false","false","false","true","false","transfer2","false",""]

The first transfer fails for insufficient funds. Only account2 can accept transfer1, and it can be accepted only once. transfer2 expires before timestamp 86400045, so its held funds are refunded and acceptance fails.

Constraints

  • 1 <= queries.length <= 500.
  • Every timestamp is a unique integer from 1 through 10^9, and queries are supplied in strictly increasing timestamp order.
  • Every query row is well formed and uses an operation available at this part.
  • Amounts and n are positive base-10 integers. Every balance and transaction total fits in a signed 64-bit integer.
  • Account identifiers are non-empty strings that do not contain commas or parentheses.

More Circle problems

See Circle hiring insights
public String[] bankingAcceptedTransfersLevel3(String[][] queries) {
  // Process the queries in order and return one string per query.
  // write your code here
}
queries[["CREATE_ACCOUNT","1","account1"],["CREATE_ACCOUNT","2","account1"],["CREATE_ACCOUNT","3","account2"],["DEPOSIT","4","non-existing","2700"],["DEPOSIT","5","account1","2700"],["PAY","6","non-existing","2700"],["PAY","7","account1","2701"],["PAY","8","account1","200"]]
expected["true", "false", "true", "", "2700", "", "", "2500"]
Checking account…