Stacks and nested operations
Validate last-in-first-out order with a stack
A trace records resources loaded inside nested scopes and unloaded as those scopes exit. Counts alone can look correct even when the nesting is wrong: LOAD:a, LOAD:b, UNLOAD:a, UNLOAD:b loads and unloads both labels, but closes the outer resource while the inner one is still active.
A stack keeps exactly the information the trace needs: which unfinished operation must close next. Sorting the tokens or counting each label would discard that order.
Checking the order of nested resources
A stack records operations that have opened but have not yet closed. A matching unload removes the most recent open label. Equality with any older label is insufficient: LOAD:a, LOAD:b, UNLOAD:a is an ordering violation even though a exists.
Closing the most recent load
Push a, then b. The only valid next unload is b, leaving a on top. An unload on an empty stack is invalid, and leftover labels at the end mean scopes never closed. Parsing also follows the trace: once an ordering violation decides the result, a later malformed token must not replace that result with a different error.
std::vector<std::string> pending{"a","b"};
// Only pending.back()=="b" may close now.Stopping at the first invalid operation
Validation order is part of this streaming contract. Parse a token only when it is reached. Once an ordering violation is detected, return false without looking ahead at later malformed tokens. Conversely, a malformed reached token is an exception, not an ordinary mismatch. Find exactly one colon, require an exact LOAD or UNLOAD command, and require a nonempty label. End-of-input succeeds only when the stack is empty. Adjacent cancellation is a possible prototype, but must retain the same left-to-right failure behavior. The stack implementation costs O(n) operations plus the text read, and stores at most the nesting depth.
Each token causes at most one push or pop, but parsing also costs time proportional to the token text inspected. Auxiliary storage follows the deepest open nesting and its labels. Repeated adjacent-pair reductions can rescan the sequence quadratically; they must still preserve the left-to-right error contract.
Use the supplied Int, Vec, and Opt aliases. Numeric arithmetic fits signed long long; absence uses std::nullopt, and documented invalid inputs throw std::invalid_argument. Keep caller-owned containers unchanged.
Balanced load/unload totals are only part of the trace contract; the resource lifetimes must also nest correctly.
Practice Stacks and nested operations
Implement the exercise in a full-screen workspace, then run its tests.