Simulate a Bank Ledger With Validated Transfers, Deposits and Withdrawals
Company: Capital One
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: medium
Interview Round: Other
A retail bank's core system keeps every account's balance in memory and must apply a stream of customer requests strictly in the order they arrive. Each request is a transfer between two accounts, a deposit, or a withdrawal. A request is rejected, and leaves every balance untouched, when it names an account that does not exist or when it would take an account's balance below zero.
Write a function that applies all requests in order and reports, for each one, whether it succeeded.
### Function Signature
```python
def process_bank_operations(balance: List[int], ops: List[str], args: List[List[int]]) -> List[bool]:
```
### Rules
- There are `n = len(balance)` accounts, numbered `1` to `n`. Account `i` starts with balance `balance[i - 1]`.
- `ops[j]` and `args[j]` describe request `j` (0-indexed). Requests are applied in index order, and each one sees the balances left by the requests before it.
- `"transfer"` with `args[j] = [from_account, to_account, money]` succeeds only if both account numbers are between `1` and `n` and the balance of `from_account` is at least `money`. On success, `money` moves from `from_account` to `to_account`. A transfer with `from_account == to_account` goes through the same checks and, if it succeeds, leaves the balance unchanged.
- `"deposit"` with `args[j] = [account, money]` succeeds only if `account` is between `1` and `n`; on success it adds `money` to that account.
- `"withdraw"` with `args[j] = [account, money]` succeeds only if `account` is between `1` and `n` and its balance is at least `money`; on success it subtracts `money`.
- A request that fails changes no balance.
- Return a list of length `len(ops)` whose element `j` is `True` if request `j` succeeded and `False` otherwise.
### Constraints
- `1 <= n <= 10^4`
- `0 <= balance[i] <= 10^11`
- `1 <= len(ops) == len(args) <= 10^4`
- Every `ops[j]` is exactly one of `"transfer"`, `"deposit"`, `"withdraw"`; `args[j]` has length 3 for a transfer and length 2 for a deposit or a withdrawal.
- Every account number in `args` satisfies `1 <= account <= 10^5`, so it may be larger than `n`.
- Every amount satisfies `0 <= money <= 10^11`.
- Balances and amounts exceed the 32-bit signed range (`2^31 - 1`), so use 64-bit integers. Under these bounds no balance ever exceeds `2 * 10^15`, well within `2^53`.
### Examples
Example 1
```text
balance = [50, 0, 75]
ops = ["deposit", "withdraw", "transfer", "transfer", "withdraw"]
args = [[2, 40], [1, 60], [3, 2, 75], [2, 4, 10], [3, 1]]
output = [True, False, True, False, False]
```
- Deposit 40 into account 2: balances become `[50, 40, 75]`.
- Withdraw 60 from account 1: only 50 is available, so it fails.
- Transfer 75 from account 3 to account 2: exactly enough, so balances become `[50, 115, 0]`.
- Transfer from account 2 to account 4: account 4 does not exist, so it fails.
- Withdraw 1 from account 3: its balance is 0, so it fails.
Example 2
```text
balance = [5]
ops = ["transfer", "withdraw", "deposit", "transfer"]
args = [[1, 1, 5], [1, 0], [2, 3], [1, 1, 6]]
output = [True, True, False, False]
```
- A self-transfer of 5 from an account holding 5 succeeds and changes nothing.
- Withdrawing 0 succeeds.
- Account 2 does not exist, so the deposit fails.
- A self-transfer of 6 fails because the balance is only 5.
Overview: A coding exercise that simulates a bank's in-memory ledger: apply an ordered sequence of transfers, deposits and withdrawals across numbered accounts and report which requests succeed. It tests careful validation of account numbers and balances, ordered state updates, and 64-bit arithmetic.
Read the full Capital One Software Engineer interview experience this question came from