Free preview

Why this matters: the vending machine's core is small enough that interviewers almost always spend the back half of the round moving the problem around — a new operational requirement, a hardware failure, a money question. Each variation below lands against a seam from lesson 02, and knowing which seam absorbs which change is the understanding being graded.

The operator arrives: restocking and service mode

We scoped the operator out of v1 while acknowledging the seam. Here's what walking through it looks like. Restocking is inventory's business — inventory.restock(slot, count) — and collection empties the cash box; neither touches the state machine's transition logic. What does touch it is service mode: while the operator has the machine open, buyers must be locked out. That's a fourth state — OutOfService — entered by an operator event, rejecting all buyer events, and it slots into the existing structure exactly the way the state design promised new states would: one new state object, transitions in and out, nothing else edited. If your states had been boolean soup, service mode would be another flag interacting with all the others.

The subtle question worth raising yourself: what happens if the operator opens the machine mid-purchase? The clean answer — service mode is only enterable from idle, or entering it refunds the inserted balance first — falls directly out of the "inserted balance is refundable until dispense" invariant.

Dispensing failures: when the hardware jams

Lesson 03's Dispensing state assumed the product actually drops. Real machines jam — and the interesting design question is what the software can know. With a drop sensor, the hardware boundary gains an event (drop confirmed / drop failed), and Dispensing grows a failure transition: the sale did not complete, so the buyer gets an automatic full refund and the slot gets flagged so the next buyer doesn't pay to hit the same jam. Notice the money implication — the refund at this point comes after the ledgers moved, so the failure path must reverse them: revenue back out of the cash box, refund from the float. This is exactly why the ledger movements were kept together in one method; a reversal is the same block, negated, not a scavenger hunt.

Without a drop sensor, the honest answer is that the software can't know — it can only track claims and let refunds be an operator process. Saying "the design depends on what the hardware can tell me, and here's both versions" is precisely the kind of boundary-awareness the round rewards.

Denominations as configuration: the change-maker's quiet dependency

The denominations were config from the start, and lesson 02 named the consequence: greedy change-making is only optimal — only correct, in the can-it-make-change sense — for well-behaved denomination sets. If the operator reconfigures the machine for a currency where that breaks, the change-maker needs the dynamic-programming variant (minimum coins for an amount given finite stock, O(amount × denominations)). The seam holds: ChangeMaker is one component with one caller, so upgrading the algorithm touches nothing else. The senior move in the round is stating the trigger for the upgrade — "greedy stays until the denomination set stops being canonical; the config validator should actually check that property" — rather than either ignoring the issue or over-building for it on day one.

There's also a stocking-policy angle: a machine that never receives small coins eventually can't make change for anyone. The float's composition, not just its total, is operational health — which leads to the last topic.

Auditing the cash: the ledgers pay off

An operator collecting the cash box wants one property above all: the money adds up. Because the design kept three ledgers with explicit movements — inserted → cash box on sale, float → buyer as change, refunds reversing cleanly — an audit trail is one append-only log of those movements away. Every dispense writes a line; the cash box total must equal the sum of sale lines since last collection. Discrepancy means a bug or a break-in, and either way the log localizes it. This mirrors a pattern you'll meet again in this course's harder problems: mutable state for operation, append-only records for truth. The vending machine is the smallest system where that split earns its keep.

Key takeaway

Every variation lands on a seam: the operator's service mode is one new state in an explicit machine, jams are a hardware-boundary event whose refund reverses the one block of ledger movements, exotic denominations upgrade the change-maker's algorithm behind its unchanged interface, and cash auditing falls out of explicit ledger movements plus an append-only log. A design defended by naming which seam absorbs which change — and what would trigger each upgrade — is what the trade-offs act is scoring.

Enjoying the preview?

Create a free account to unlock the rest of this course, the in-browser judge, and live AI mock interviews.

Sign up free to continue