A contract defines which outputs count as correct
Generated code is a proposed implementation. Its explanation can sound convincing even when the implementation violates the request. Start by writing the input domain and the required relationship between input and output. This contract gives you a way to check the code independently of its explanation.
For a duplicate detector, the input is a finite sequence of integers in any order. The output is true exactly when two different positions contain equal values. Empty and one-element sequences return false. These statements apply in any programming language. Memory representation and library costs belong to a particular implementation.
A test compares the implementation with an expected result. For a small case, derive that result by hand from the contract. For many cases, use a simple reference implementation whose reasoning you can inspect. Two generated implementations can share the same mistake, so agreement between them alone is weak evidence.
One valid counterexample disproves a universal claim
If a program is claimed to work for every allowed input, one allowed input with the wrong output refutes that claim. A successful test establishes behavior only on that input. This asymmetry makes counterexample search useful when reviewing generated code.
Suppose the proposed detector compares each item only with its immediate predecessor. It returns true for adjacent duplicates such as [4, 4]. But the contract permits equal values separated by another item. On [4, 9, 4], both adjacent comparisons differ, so the proposal returns false although the required result is true.
Reduce a failure while preserving the mismatch. Removing 9 from that example changes it to adjacent duplicates, which the proposal handles correctly. Three elements are enough to isolate the missing comparison. A small reproducer makes the faulty assumption easier to explain and retain in a regression suite.
Explain the missing invariant before changing the code
A complete scan can keep a set of values seen earlier. Before processing position i, the set contains exactly the values from positions before i. If the current value is already present, a repeated value exists. Otherwise add it and continue. Returning false after the scan means each value appeared at most once.
This argument covers separated duplicates because the set represents the whole processed prefix. The adjacent-only proposal stores too little history to support that invariant. With a typical hash-set implementation, the scan uses expected O(n) time and O(n) extra space; the exact guarantees depend on the chosen language and collection.
After a repair, rerun the counterexample and examples with empty input, one value and all distinct values. Property-based testing can generate many inputs and shrink failures, but its results still depend on the domain and property you specify. Keep the human-readable contract alongside the tests.
Try the skill
Contract: return true if any two positions contain the same integer. Values may appear in any order. Find an input where this generated JavaScript function returns the wrong answer.
JavaScript
function hasDuplicate(values) { for (let i = 1; i < values.length; i++) { if (values[i] === values[i - 1]) return true; } return false;}