PracHub
QuestionsCoachesLearningGuidesInterview Prep

Quick Overview

Implement a progressive banking system with accounts, activity rankings, reserved expiring transfers, acceptance, and account merges. The practice contract tests timestamped event processing, available versus reserved balances, transfer accounting, retired IDs, and atomic state transitions.

  • medium
  • Instacart
  • Coding & Algorithms
  • Software Engineer

Build a Progressive Banking System

Company: Instacart

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Technical Screen

# Build a Progressive Banking System The source reports progressive account, activity-ranking, expiring-transfer, and merge features but not exact return shapes or transfer-accounting rules. The API, event behavior, and activity definition below are deterministic practice assumptions. Implement: ```python def run_banking_system( operations: list[list[object]], expiry_duration: int, ) -> list[object]: ... ``` `expiry_duration` is a positive integer. Operation timestamps are nonnegative and nondecreasing; equal timestamps execute in list order. Return one result per operation. ## Stage 1: Accounts and Balances - `["CREATE", timestamp, account_id] -> bool` creates an account with zero available and reserved balance. Duplicate or retired IDs return `False`. - `["DEPOSIT", timestamp, account_id, amount] -> int | None` returns the new available balance, or `None` for a non-active account. - `["PAY", timestamp, account_id, amount] -> int | None` subtracts available funds and returns the new available balance. It returns `None` for a non-active account or insufficient funds. Amounts are positive integers. Failed operations do not change account aggregates after mandatory expiration processing. ## Stage 2: Activity Ranking - `["TOP_ACTIVITY", timestamp, n] -> list[list[object]]` returns `[[account_id, activity], ...]` for up to `n` active accounts, sorted by activity descending and account ID ascending. Return `[]` when `n <= 0`. Activity uses these exact rules: - A successful deposit adds `amount` to the receiving account. - A successful payment adds `amount` to the paying account. - An accepted transfer adds `amount` to both its source and its target. - Initializing, expiring, or canceling a transfer adds no activity. Failed operations add none. ## Stage 3: Expiring Transfers - `["INIT_TRANSFER", timestamp, source_id, target_id, amount] -> str | None` returns sequential IDs `txn1`, `txn2`, and so on, or `None` for missing/equal accounts or insufficient available funds. Only successful initializations consume the next ID. - `["ACCEPT", timestamp, target_id, transaction_id] -> bool` accepts a pending transfer only when `target_id` is its current intended target and the operation occurs before expiration. - `["STATUS", timestamp, transaction_id] -> str | None` returns `"pending"`, `"accepted"`, `"expired"`, or `"canceled_by_merge"`, or `None` for an unknown ID. Initialization moves `amount` from source available balance to source reserved balance. A successful acceptance removes it from source reserved balance, adds it to target available balance, updates both activity totals, and can occur only once. The expiration time is `created_at + expiry_duration`, and acceptance is valid only when `timestamp < expiration_time`. Before every well-formed operation at timestamp `t`, expire all pending transactions with `expiration_time <= t`, ordered by expiration time and numeric transaction ID. Expiration returns reserved funds to the transaction's current source. Consequently, `ACCEPT` at the exact expiration timestamp returns `False` after the release. ## Stage 4: Account Merging - `["MERGE", timestamp, target_id, source_id] -> bool` combines two distinct active accounts. The target survives and the source becomes a retired ID that cannot be recreated or used by new account operations. After processing expirations, add the source's available balance, reserved balance, and activity to the target. Rewrite every pending transfer endpoint equal to the source so it names the target. If that rewrite makes a pending transfer's source and target equal, mark it `"canceled_by_merge"` and release its reservation from the survivor's reserved balance to its available balance. Other pending inbound and outbound transfers continue normally under the surviving endpoint. Accepted and expired transaction records remain unchanged and every transaction ID remains queryable through `STATUS`. After a target account is itself merged later, pending endpoints follow the new survivor. `ACCEPT` must name the current active target ID; a retired alias is not valid input. ## Invariants and Errors - For each active account, total held funds equal `available + reserved`; neither component may be negative. - Initialization moves funds between those components, expiration reverses that move, acceptance transfers total funds between accounts, and merging preserves system-wide total funds. - Account IDs are nonempty strings. Validate command shape, types, IDs, timestamp order, positive amounts, and positive constructor duration before processing expirations. Invalid input or an unknown command raises `ValueError` without state change. - Ordinary domain failures use exactly `False` or `None` as documented; due expirations processed before such a failure remain committed. Analyze point operations, expiration processing, ranking, pending-endpoint rewrites, and merge complexity. Test exact expiration, double acceptance, internal transfers canceled by merge, chained merges, activity ties, and pending inbound and outbound transfers across a merge.

Quick Answer: Implement a progressive banking system with accounts, activity rankings, reserved expiring transfers, acceptance, and account merges. The practice contract tests timestamped event processing, available versus reserved balances, transfer accounting, retired IDs, and atomic state transitions.

Process account, activity, expiring reserved transfer, acceptance, status, and merge operations with deterministic expiration and endpoint-rebinding rules.

Constraints

  • Timestamps are nonnegative and nondecreasing
  • Expiration at time t occurs before the external operation at t
  • Merged account IDs are retired permanently

Examples

Input: {'operations': [], 'expiry_duration': 3}

Expected Output: []

Explanation: An empty operation stream has no results.

Input: {'operations': [['CREATE', 0, 'a'], ['CREATE', 0, 'b'], ['DEPOSIT', 1, 'a', 10], ['PAY', 2, 'a', 3], ['TOP_ACTIVITY', 3, 2]], 'expiry_duration': 5}

Expected Output: [True, True, 10, 7, [['a', 13], ['b', 0]]]

Explanation: Deposits and payments both add to activity.

Hints

  1. Track available and reserved balances separately for every active account.
  2. Before a merge finishes, rewrite each pending endpoint and cancel transfers that become internal.
Last updated: Jul 15, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • AI Coding Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Fix the Broken Search Filter in a Book Catalog API - Instacart (medium)
  • Find Largest Adjacent Stock Price Change - Instacart (medium)
  • Implement an In-Memory File Storage System - Instacart (medium)
  • Decode an encoded string - Instacart (medium)