~/problems / Arrays & hashing / Hash maps and counting

Percentage transfers between accounts

easy ~20 min Coinbase

A wallet service moves money between accounts in chunks that are a percentage of the sender's current balance. Balances are whole numbers of cents.

Implement TransactionSystem:

  • __init__(accounts: list[tuple[str, int]]): the starting accounts as (name, balance) pairs. Names are unique; balances are >= 0.
  • transfer(sender: str, receiver: str, percent: int) -> int: move floor(balance(sender) * percent / 100) cents from sender to receiver, using the sender's balance at this moment, and return the amount moved. The transfer is invalid if either account doesn't exist, sender == receiver, or percent is outside 0..100; then nothing changes and it returns -1.
  • process(transactions: list[tuple[str, str, int]]) -> list[int]: apply (sender, receiver, percent) transfers in order and return what each transfer call returned. Invalid ones are skipped (their entry is -1) and processing continues.
  • balance(name: str) -> int | None: the current balance, or None for an unknown account.
  • richest(k: int) -> list[str]: the names of the k accounts with the highest balances, highest first, ties broken by name ascending. If there are fewer than k accounts, return them all.
ts = TransactionSystem([("ana", 1000), ("ben", 500), ("cy", 0)])
ts.transfer("ana", "ben", 25)      # 250   ana 750, ben 750
ts.transfer("ben", "cy", 33)       # 247   floor(750 * 33 / 100); ben 503, cy 247
ts.process([("cy", "ana", 100), ("ana", "zed", 10), ("ana", "ana", 5)])
# [247, -1, -1]                    ana 997, cy 0
ts.richest(2)                      # ["ana", "ben"]
ts.balance("zed")                  # None

Up to 10^5 accounts and transfers. Every transfer must be O(1). richest is called only a few times, so O(n log n) per call is fine.

Show hint

A dict from name to balance does all the work. Compute the amount with integer arithmetic (balance * percent // 100), not floats, so that large balances round exactly.

Topic: Hash maps and counting. Counter/defaultdict, complement lookups, prefix-sum + hash map.

Read the visual guide
0:00
Ctrl ' run · Ctrl ↵ submit
esc