Use only in-memory state. Identifiers are nonempty strings supplied by the caller. Amounts and limits are integers within the declared C++ numeric type. There are no timestamps, threads, persistence, or external services.
Prototype: implement BalanceAccount() with initial balance zero. balance() returns the integer balance. deposit(amount) requires amount > 0, adds it, and returns the new balance. withdraw(amount) requires amount > 0; return false without mutation if funds are insufficient, otherwise debit and return true. Invalid amounts raise std::invalid_argument without mutation.
Final: implement Bank():
create_account(): create a zero-balance account and zero outgoing total; returnfalseon a duplicate without resetting it.balance(): return the balance, ornulloptfor an unknown account.deposit(): reject nonpositive amounts withstd::invalid_argumentfirst; returnnulloptfor an unknown account, otherwise return its new balance.transfer(): reject a nonpositive amount withstd::invalid_argumentfirst. A previously successful request with exactly the same(source, target, amount)returns its original(source_balance, target_balance). Reusing that identifier with different arguments raisesstd::invalid_argument. Otherwise returnnulloptwithout mutation for missing accounts, identical accounts, or insufficient funds. On success move the amount, add it only to the source's outgoing total, record the successful request, and return the two resulting balances. Failures do not consume request identifiers.top_spenders(): return at mostlimitaccounts ordered by outgoing total descending, then identifier ascending. Include zero-spending accounts. Zero returns[]; negative limits raisestd::invalid_argument. The list is a fresh snapshot.
All raised errors and rejected requests preserve state. Separate instances are independent.
The public C++ API below is authoritative for field types and return values. erase is used where another language might use a method named delete, because delete is a C++ keyword. Returned records are value snapshots with the documented named fields; mutating a record or its nested vectors cannot affect the service.
class BalanceAccount { public:
BalanceAccount();
Int balance() const;
Int deposit(Int amount);
bool withdraw(Int amount);
};
class Bank { public:
Bank();
bool create_account(const std::string& id);
Opt<Int> balance(const std::string& id) const;
Opt<Int> deposit(const std::string& id,Int amount);
Opt<Pair> transfer(const std::string& request,const std::string& source,const std::string& target,Int amount);
Vec<std::pair<std::string,Int>> top_spenders(Int limit) const;
};Compile and run from this directory:
c++ -std=c++20 -O2 -Wall -Wextra -pedantic -pthread main.cpp -o practice
./practice --stage prototype
./practice --stage finalEdit exercise.hpp. Both stages start unfinished and must report failures until implemented. Keep main.cpp as the executable contract. The runner returns nonzero for a failed check, an unexpected exception, an invalid stage, or an empty suite. C++20 and only the standard library are required.
Complete the starter code, then run the checks.
Results and errors will appear here.
C++ runtime powered by Wasmer.