Why doesn't a greedy rule passing every test case you tried prove it optimal?
answer
- What would a proof have to cover?
- Tests sample; correctness covers all inputs
- Where do counterexamples cluster, really?
- Local win can strand an expensive remainder
- Greedy-choice property is proved, not sampled
basics
~20 sPassing cases shows only that no input you happened to choose exposed the flaw. Greedy optimality is a claim about every input, and it rests on the greedy-choice property: the locally best move must be consistent with some optimal solution.
solid answer
~50 sTests sample the input space; correctness quantifies over all of it, and the counterexamples that kill greedy rules are usually structured rather than random — they are the inputs where a cheap local win strands you into an expensive remainder. Look at the pass-buying rule in the fragment: at each unpaid travel date it takes the largest pass whose break-even count is met. That is defensible-looking and survives ordinary calendars, but the property it needs is that some optimal purchase plan starts with the pass this rule picks, and nothing in the rule establishes that — a cluster just outside the window can make an earlier, smaller purchase the better opening move. So the burden is a proof of the greedy-choice property, not a green test run. Randomized differential search against an exhaustive solver is strong evidence of a bug, never evidence of correctness.
code
pseudocode · 13 lines... travel holds the travel dates in increasing order
i = 0
cost = 0
while i < length(travel):
if trips_in_window(travel, i, SEASON_LEN) >= SEASON_BREAKEVEN:
cost = cost + SEASON_PRICE
i = first_index_after(travel, travel[i] + SEASON_LEN)
else if trips_in_window(travel, i, WEEK_LEN) >= WEEK_BREAKEVEN:
cost = cost + WEEK_PRICE
i = first_index_after(travel, travel[i] + WEEK_LEN)
else:
cost = cost + SINGLE_PRICE
i = i + 1go deeper
Be ready to say that a greedy rule is a claim about every possible input, and that examples can only disprove it. Name the shape of a failure: an early cheap choice that makes the rest expensive.
Explain the greedy-choice property in your own words and attach it to the rule you propose as an explicit obligation. An interviewer expects you to notice when you cannot discharge it and to start hunting a counterexample.
Demonstrate how you would find the counterexample deliberately — boundary-biased generation against an exhaustive oracle on small inputs — and be clear that this refutes but never confirms.
Own the asymmetry as a policy: unproven greedy rules ship as heuristics with a measured gap and an oracle in the test suite, never as 'optimal'. Decide what a suboptimal answer actually costs the business before allowing it.
## What a greedy algorithm is claiming A greedy algorithm makes one irrevocable choice at each step by a local rule and never reconsiders. That is an extraordinarily strong claim: that a decision made with no knowledge of the rest of the input is never regretted. Two properties have to hold for it. - **The greedy-choice property.** There exists an optimal solution that agrees with the choice the rule makes first. If that holds at every step, the rule can be followed all the way down without ever leaving optimality behind. - **Optimal substructure.** After the choice is fixed, what remains is a smaller instance of the same problem, and solving that optimally completes an optimal whole. The second is shared with dynamic programming and is not what usually breaks. The first is what greedy rules die on, and it is the one nobody proves. ## Why the test suite cannot supply the proof A correctness claim is universally quantified: *for every* input, the rule's output cost equals the optimum. A test run is an existential observation: *for these* twelve inputs, it did. No number of passing samples closes that gap, and the gap is not small, because the inputs that break greedy rules are not spread uniformly through the space. They are narrow and structured — the tie, the value just under a threshold, the cluster that sits one unit outside a window. Hand-written test cases and uniform random generators both under-sample exactly the region where greedy rules fail, because a human writes the case they were already thinking about and a uniform generator almost never lands on a boundary configuration. ## Reading the pass-buying rule The fragment walks the travel dates in order. At the first date not yet covered, it counts how many travel dates fall inside a season-length window; if that count reaches the season break-even, it buys the season pass and jumps past the window. Otherwise it tries the same test at week length, and failing both it buys a single fare and advances one date. Every clause is locally reasonable, and the rule is internally consistent — there is no off-by-one to find. The question is whether starting with the largest qualifying pass is ever wrong. Consider travel that is sparse for a stretch and then dense just after the window the rule would buy: opening with a *smaller* purchase can realign the later, larger pass so it swallows the dense stretch, and the total falls. The rule cannot see that, because it decides using only the dates inside the current window. The property it needs — that some optimal plan opens with this pass — is precisely the thing that fails. ## What actually settles the question - **To claim optimality:** a proof of the greedy-choice property at each step. Nothing weaker is a claim; it is a hope. - **To refute optimality:** one input on which the rule's cost exceeds the true optimum. That is why differential search — generate structured inputs, run the rule against an exhaustive or tabulated solver, compare costs — is such good value. It cannot prove the rule right, but it finds the counterexample far faster than intuition does, and finding one ends the argument. Note the asymmetry: evidence of a bug is cheap and conclusive; evidence of correctness is expensive and only ever a proof. ## The mirror mistake, which is just as common Having found a counterexample, the reflex is "so it is dynamic programming". That does not follow either. One counterexample establishes exactly one thing: *this rule* is not optimal. It leaves open that a different local rule is provably optimal (many problems have a non-obvious ordering that works), that the problem admits a clean recurrence with a small state space, or that neither applies and the practical answer is search with pruning. Two failed candidate rules do not add up to a theorem about the problem, in either direction. So the discipline is symmetrical. Do not promote a rule to "correct" on the strength of samples, and do not condemn a paradigm on the strength of one broken instance of it. Each direction has its own obligation: a proof going one way, a counterexample going the other. ## What good sounds like in the room When you propose a greedy solution, propose it with its proof obligation attached: "I'll take the largest qualifying pass first — that is optimal if I can show some optimal plan opens with it, and here is my argument." If the argument does not come, say so and start looking for the counterexample yourself. Interviewers are far more impressed by a candidate who says "I cannot justify this greedy choice, so let me look for a case where an earlier small purchase realigns a later big one" than by one who runs three examples and declares victory.
- You find a counterexample. Does that mean the problem needs dynamic programming?No. It rules out that one rule and nothing else. A different local ordering may still be provably optimal, the problem may have a clean recurrence over a small state space, or neither may apply and search with pruning is the honest answer. One broken rule is a fact about the rule, not a classification of the problem.
- How would you hunt for the counterexample instead of hoping for one?Generate inputs biased toward the structure the rule reasons about: counts sitting exactly at and just below each break-even, clusters straddling a window edge, long sparse gaps followed by dense bursts. Compare the rule's cost against an exhaustive solver on small instances. Boundary-biased generation finds these far faster than uniform random input.
- If the greedy rule is unproven but always matched the optimum on real traffic, can you ship it?Possibly, but say what you are shipping: a heuristic with a measured gap, not an optimal algorithm. That means recording the observed gap distribution, keeping the exhaustive solver as a test oracle, and knowing what a suboptimal answer costs. Shipping it silently as 'correct' is the part that is indefensible.
A lock that opened for every key you happened to try is not a lock you have tested; it is a lock nobody has attacked yet.
saying these in an interview costs you the question
- It passed all my test cases, so it is correct
- Greedy is right whenever the choices look obvious
- Random testing can establish optimality
- One counterexample means the problem is dynamic programming
- Greedy needs no proof because it is simple
- Counterexamples show up in ordinary random inputs