JJobsMoi
Anthropic

Banking System (Online Assessment)

Coding

Problem

Overview

Your task is to implement an in-memory banking system. This problem consists of 4 levels that progressively add complexity:

  1. Level 1: Basic account operations (create, deposit, transfer)
  2. Level 2: Ranking accounts by spending activity
  3. Level 3: Scheduled payments with cashback and payment status tracking
  4. Level 4: Account merging and historical balance queries

Subsequent levels are unlocked when the current level is correctly solved. You always have access to the data for the current and all previous levels.


Level 1: Basic Account Operations

Description

Initially, the banking system does not contain any accounts. Implement operations to allow account creation, deposits, and transfers between different accounts.

Operations

create_account

create_account(self, timestamp: int, account_id: str) -> bool
  • Creates a new account with the given identifier if it doesn't already exist
  • Returns True if the account was successfully created
  • Returns False if an account with that id already exists

deposit

deposit(self, timestamp: int, account_id: str, amount: int) -> int | None
  • Deposits the given amount of money to the specified account id
  • Returns the balance of the account after the operation has been processed
  • Returns None if the specified account doesn't exist
  • The operation is processed before the result is returned

transfer

transfer(self, timestamp: int, source_account_id: str, target_account_id: str, amount: int) -> int | None
  • Transfers the given amount of money from source_account_id to target_account_id
  • Returns the balance of source_account_id if the transfer was successful
  • Returns None otherwise

Returns None if:

  • source_account_id or target_account_id doesn't exist
  • source_account_id and target_account_id are the same
  • Account source_account_id has insufficient funds to perform the transfer

Level 2: Top Spenders

Description

The bank wants to identify people who are not keeping money in their accounts. Implement operations to support ranking accounts based on outgoing transactions.

New Operations

top_spenders

top_spenders(self, timestamp: int, n: int) -> list[str]
  • Returns the identifiers of the top n accounts with the highest outgoing transactions
  • Outgoing transactions = total amount of money either:
    • Transferred out, OR
    • Paid/withdrawn (the pay operation will be introduced in Level 3)
  • Results are sorted in descending order by total outgoing amount
  • In case of a tie, sort alphabetically by account_id in ascending order

Format:

["account_id_1(total_outgoing_1)", "account_id_2(total_outgoing_2)", ..., "account_id_n(total_outgoing_n)"]

Notes:

  • If less than n accounts exist in the system, return all their identifiers in the described format
  • Cashback (an operation introduced in Level 3) should not be reflected in calculations for total outgoing transactions

Level 3: Scheduled Payments with Cashback

Description

The banking system should allow scheduling payments with cashback and checking the status of scheduled payments.

New Operations

pay

pay(self, timestamp: int, account_id: str, amount: int) -> str | None
  • Withdraws the given amount of money from the specified account
  • All withdrawal transactions provide a 2% cashback
  • The cashback amount (rounded down to the nearest integer) will be refunded to the account 24 hours after the withdrawal
  • Returns a unique identifier for the payment transaction (e.g., "payment1", "payment2", etc.)

Returns None if:

  • account_id doesn't exist
  • account_id has insufficient funds to perform the payment

Additional Conditions:

  • top_spenders should now also account for the total amount of money withdrawn from accounts
  • The waiting period for cashback is 24 hours = 24 × 60 × 60 × 1000 = 86400000 milliseconds (the unit for timestamps)
  • Cashback will be processed at timestamp + 86400000
  • If the refund is successful (i.e., the account hasn't been removed from the system), the cashback is applied

get_payment_status

get_payment_status(self, timestamp: int, account_id: str, payment: str) -> str | None
  • Returns the status of the payment transaction for the given payment

Returns None if:

  • account_id doesn't exist
  • The given payment doesn't exist for the specified account
  • The payment transaction was for an account with a different identifier from account_id

Returns:

  • "IN_PROGRESS" - if cashback has not been received yet
  • "CASHBACK_RECEIVED" - if cashback has been refunded to the account

Level 4: Account Merging and Historical Balances

Description

The banking system should support merging two accounts while retaining both accounts' balance and transaction histories.

New Operations

merge_accounts

merge_accounts(self, timestamp: int, account_id_1: str, account_id_2: str) -> bool
  • Merges account_id_2 into account_id_1
  • Returns True if accounts were successfully merged
  • Returns False otherwise

Returns False if:

  • account_id_1 is equal to account_id_2
  • account_id_1 or account_id_2 doesn't exist

Merge Behavior:

  • All pending cashback refunds for account_id_2 should still be processed, but refunded to account_id_1 instead
  • After the merge, it must be possible to check the status of payment transactions in account_id_2 with payment identifiers by replacing account_id_2 with account_id_1
  • The balance of account_id_2 should be added to the balance for account_id_1
  • top_spenders operations should recognize merged accounts — the total outgoing transactions for merged accounts should be the sum of all money transferred and/or withdrawn in both accounts
  • account_id_2 should be removed from the system after the merge

get_balance

get_balance(self, timestamp: int, account_id: str, time_at: int) -> int | None
  • Returns the total amount of money in the account account_id at the given timestamp time_at
  • If the specified account did not exist at a given time time_at, returns None

Important Notes:

  • If queries have been processed at timestamp time_at, get_balance must reflect the account balance after the query has been processed
  • If the account was merged into another account, the merged account should inherit its balance history

Important Edge Cases

Account Recreation After Merge

  • If account_id_2 is merged into account_id_1, then account_id_2 is removed from the system
  • After removal, it is possible to create a new account with account_id_2 using create_account
  • Historical balances and outgoing transaction totals before the merge are preserved in account_id_1
  • The new account_id_2 account starts with a balance of 0 from the new creation timestamp

Historical Queries After Merge

  • If an account was merged at timestamp T, queries with time_at < T should return the account's historical balance
  • Queries with time_at >= T for a merged account should return None (unless the account was recreated)

Constraints

  • All timestamps are given in milliseconds
  • Timestamps are guaranteed to be unique and in strictly increasing order
  • Account IDs are valid string identifiers
  • All amounts are positive integers

Solution

Loading editor…

Sign in to get AI feedback on your answer. Your work is saved while you do.

Sign in to evaluate