Katkat

Implement a Banking System

AnthropicSoftware Engineer · Onsite

Last updated

This question evaluates skills in designing and implementing a stateful in-memory banking system, covering account modeling, transfer lifecycle and expiration handling, balance management, and tracking aggregate outgoing amounts.

Design and implement an in-memory banking system.

All operations are processed in non-decreasing timestamp order. Account identifiers are strings. Money amounts are non-negative integers. A transfer expires if it has not been accepted within TRANSFER_EXPIRATION_MS = 86,400,000 milliseconds after it was created.

Implement the following operations:

  1. create_account(timestamp, account_id) -> bool
  • Create a new account with balance 0.
  • Return true if the account was created.
  • Return false if an account with the same id already exists.
  1. deposit(timestamp, account_id, amount) -> int | null
  • Before applying the deposit, expire any pending transfers that should have timed out by this timestamp.
  • Add amount to the account balance.
  • Return the new balance.
  • Return null if the account does not exist.
  1. top_outgoing(timestamp, n) -> list[string]
  • Before computing the result, expire any pending transfers that should have timed out by this timestamp.
  • Return up to n accounts sorted by total outgoing money in descending order.
  • Break ties by lexicographically smaller account id.
  • Outgoing money includes only completed outgoing transfers. Pending or expired transfers must not count.
  1. transfer(timestamp, source_account_id, target_account_id, amount) -> string | null
  • Before creating the transfer, expire any pending transfers that should have timed out by this timestamp.
  • Create a pending transfer from source_account_id to target_account_id.
  • Immediately withhold amount from the source account balance.
  • Return a unique transfer id such as "transfer1", "transfer2", etc.
  • Return null if either account does not exist, both accounts are the same, or the source account has insufficient available balance.
  1. accept_transfer(timestamp, account_id, transfer_id) -> bool
  • Before accepting the transfer, expire any pending transfers that should have timed out by this timestamp.
  • Accept the pending transfer only if account_id is the target account.
  • Move the withheld money into the target account balance.
  • Add amount to the source account's total outgoing money.
  • Return true if the transfer was accepted.
  • Return false if the transfer does not exist, is already accepted, has expired, or account_id is not the target account.
  1. merge_accounts(timestamp, destination_account_id, source_account_id) -> bool
  • Before merging, expire any pending transfers that should have timed out by this timestamp.
  • Merge source_account_id into destination_account_id.
  • Return false if either account does not exist or both ids are the same.
  • Add the source account's balance to the destination account's balance.
  • Add the source account's total outgoing money to the destination account's total outgoing money.
  • Redirect pending incoming transfers targeting the source account so that they now target the destination account.
  • Redirect pending outgoing transfers created by the source account so that they now originate from the destination account; the withheld balance remains withheld.
  • If there is a pending transfer between the destination and source accounts, cancel it and return the withheld amount to the appropriate surviving account.
  • Remove the source account after the merge.

Your implementation should correctly handle edge cases such as expired transfers being canceled before later deposits, attempts to accept expired transfers, duplicate account creation, insufficient funds, and sorting ties in top_outgoing.