CITYBANK Coding Question – Solved

7 Live
You've been asked to program a bot for a popular bank that will automate the management of incoming requests. Every request has its own timestamp in seconds, and it is guaranteed that all requests come sequentially, i.e. the timestamp is strictly increasing. There are two types of incoming requests: . deposit <timestamp> <holder_id> <amount> - request to deposit <amount> amount of money in the <holder_id> account; . withdraw <timestamp> <holder_id> <amount> - request to withdraw <amount> amount of money from the <holder_id> account. As a bonus, the bank also provides a cashback policy - 2% of the withdrawn amount rounded down to the nearest integer will be returned to the account exactly 24 hours after the request timestamp. If the cashback and deposit/withdrawal happen at the same timestamp, assume cashback happens earlier. Your system should also handle invalid requests. There are two types of invalid requests: . invalid account number; . withdrawal of a larger amount of money than is currently available. For the given list of initial balances and requests, return the state of balances straight after the last request has been processed, or an array of a single element [-<request_id>] (please note the minus sign), where <request_id> is the 1-based index of the first invalid request. Note that cashback requests which haven't happened before the last request timestamp should be ignored. Example Example 1: For balances = [1000, 1500] and requests = ["withdraw 1613327630 2 480", "withdraw 1613327644 2 800", "withdraw 1614105244 1 100", "deposit 1614108844 2 200", "withdraw 1614108845 2 150"], the output should be solution(balances, requests) = [900, 295]. Explanation: Here are the states of balances after each request: . Initially: [1000, 1500]; . "withdraw 1613327630 2 480": [1000, 1020]; . "withdraw 1613327644 2 800": [1000, 220]; . At 1613414030 the 2nd account will receive the cashback of 480 * 0.02 = 9.6, which is rounded down to 9: [1000, 229]; . At 1613414044 the 2nd account will receive the cashback of 800 * 0.02 = 16: [1000, 245]; . "withdraw 1614105244 1 100": [900, 245]; . At 1614191644 the 1st account will receive cashback of 2: [902, 245]; . "deposit 1614108844 2 200": [902, 445]; . "withdraw 1614108845 2 150": [902, 295]; . Final state: [902, 295]. Example 2: For balances = [20, 1000, 500, 40, 90] and requests = ["deposit 1613327630 3 400", "withdraw 1613327635 1 20", "withdraw 1613327651 1 50", "deposit 1613327655 1 50"], the output should be solution(balances, requests) = [-3]. Explanation: Here are the states of balances after each request: . Initially: [20, 1000, 500, 40, 90]; . "deposit 1613327630 3 400": [20, 1000, 900, 40, 90]; . "withdraw 1613327635 1 20": [0, 1000, 900, 40, 90]; . "withdraw 1613327651 1 50": it is not possible to withdraw 50 from the 1st account, so the request is invalid; . The rest of the requests are not processed. Input/Output . [execution time limit] 4 seconds (py3) . [memory limit] 1 GB . [input] array.integer balances: Array of integers, where balances[i] is the amount of money in the (i + 1)th account. Guaranteed constraints: 1 ≤ balances.length < 100

Asked in: CITYBANK

Image of the Question

Question Image Question Image Question Image Question Image

All Testcases Passed ✔



Passcode Image

Solution


import heapq
def solution(balances, requests):
    balances = [0]+balances[::]
    timeaddition = 24*60*60
// ... rest of solution available after purchase

🔒 Please login to view the solution

Explanation


```
To solve this problem, start by carefully understanding the sequence of events and constraints involved in processing requests on bank accounts.

---

Step 1: Understand the Problem Setting

You have a list of initial balances, where each index corresponds to a unique account (1-based indexing). You then receive a sequence of timestamped requests, strictly ordered by time, which are either deposits or withdrawals on specific accounts.

Key rules:
- Deposit requests add money immediately to the account.
- Withdrawal requests subtract money immediately if the account has sufficient balance; otherwise, they are invalid.
- Withdrawals also generate a cashback of 2% of the withdrawn amount (rounded down), credited exactly 24 hours (86400 seconds) after the withdrawal timestamp.
- If a cashback and a deposit/withdrawal happen at the same timestamp, cashback is processed first.

Invalid requests occur if:
- The account number does not exist.
- A withdrawal is requested for more money than is available.

If an invalid request is encountered, processing stops immediately and the output is [-request_id], where request_id is the 1-based index of the invalid request.

If all requests are valid, output the balances immediately after processing the last request, ignoring any cashback that would occur after that time.

---

Step 2: Data Structures and Event Handling

Since cashback happens 24 hours after a withdrawal, you need a mechanism to schedule these future cashback deposits.

One way to do this is to maintain a priority queue or a sorted structure keyed by cashback timestamps. Before processing each incoming request at timestamp T, first process all pending cashback events scheduled at timestamps ≤ T, applying them to their respective accounts.

Remember that cashback happens before any other event at the same timestamp, so if a cashback and a request share the same timestamp, apply cashback first.

---

Step 3: Processing the Requests Sequentially

Iterate over the requests in order:

- Before processing the current request, process all cashback events with timestamps ≤ current request timestamp. For each, add the cashback amount to the relevant account balance.

- Parse the current request, extract the type (deposit/withdraw), timestamp, account id, and amount.

- Validate the account id (must be between 1 and the number of accounts).

- For deposits, simply add the amount to the account balance.

- For withdrawals, check if the balance in the account is sufficient; if not, return an invalid request result immediately. If sufficient, subtract the amount from the balance, and schedule a cashback event at timestamp + 86400 seconds. The cashback amount is floor(2% of withdrawn amount).

---

Step 4: Handling Cashback Events

To efficiently process cashback events:

- Keep cashback events sorted by timestamp, or use a priority queue (min-heap) to quickly access the earliest pending cashback.

- Before each request processing, pop all cashback events with timestamps ≤ current request timestamp, and apply them.

- After processing all requests, no cashback after the last request timestamp is applied, so ignore them.

---

Step 5: Corner Cases and Edge Conditions

- Requests must be processed strictly in the order they appear because timestamps are strictly increasing.

- When a cashback and a request share the same timestamp, cashback must be applied first before processing the request.

- Be careful with rounding down the cashback amount.

- Invalid account numbers can appear anytime.

- If a withdrawal is invalid, immediately stop processing further requests and output the negative index.

---

Step 6: Final Output

If all requests are valid, return the final balances immediately after processing the last request, ignoring cashback that has not yet happened.

If an invalid request was encountered, return the negative index of that request (1-based).

---

Step 7: Summary of Approach

- Use a data structure to keep track of scheduled cashback events (timestamp, account, amount).

- Iterate through requests in order; before each, process all applicable cashback events.

- Validate accounts and balances at each request.

- Schedule cashback for withdrawals.

- Stop immediately on invalid request and return appropriate output.

- After processing all requests, output current balances.

This approach ensures the problem's temporal dependencies are respected and invalid requests are detected early, with cashback timing handled precisely.
```


Related Questions