Compare against an answer you trust
You almost always have two solutions: the fast one you submitted and the slow one you thought of first. The slow one is easy to get right because there’s nothing clever in it. Run both on thousands of small random inputs and stop at the first disagreement. When they disagree, the fast one is wrong, or both are, which you also want to know.
Keep the inputs small. An array of length 5 with values from -5 to 5 hits negatives, zeros, duplicates and single elements, and it’s short enough to trace by hand. The method works for anything with an exact answer you can compute slowly: sums, counts, shortest paths on tiny graphs, DP you can brute-force over every choice.
The three parts
In a contest, put all three in the same file, as in the example below. Outside one, some people keep a script that runs two separate programs and compares their output.
A generator that makes one small random input.
A brute force that is slow and obviously correct.
A loop that runs both and prints the first input where they differ.
Run it on a real bug
The program below tests a maximum-subarray solution with a common bug. The best sum starts at 0, so on an array of only negative values it returns 0 instead of the largest value. Samples with a positive number pass, so the bug survives until the judge’s tests.
The stress test finds it on test 5, an array holding a single -2. Both versions use the same small random number generator, so Python and C++ find the same input. Seed your own generator with a fixed number too, so a failing case comes back the same way on every run.
seed = 2026
def rand(lo, hi):
# A small linear congruential generator, so Python and C++ draw the same tests.
global seed
seed = (seed * 1103515245 + 12345) % 2147483648
return lo + seed % (hi - lo + 1)
def brute(a):
# Every subarray: slow, but easy to trust.
return max(sum(a[i:j + 1]) for i in range(len(a)) for j in range(i, len(a)))
def fast(a):
# Kadane's algorithm with a bug: the best sum starts at 0.
best = current = 0
for x in a:
current = max(x, current + x)
best = max(best, current)
return best
for test in range(1, 1001):
n = rand(1, 5)
a = [rand(-5, 5) for _ in range(n)]
if brute(a) != fast(a):
print("test", test, "fails:", a)
print("expected", brute(a), "got", fast(a))
break
else:
print("all 1000 tests agree")test 5 fails: [-2] expected -2 got 0
When to reach for it
Reach for a stress test the second time a problem gets Wrong answer. The first time, reread the statement: a misread output format is quicker to fix than any test.
Once you have the failing input, trace your code on it with a few prints. A tiny input keeps the trace short. If small inputs all agree, raise the limits a little at a time. A bug that needs n = 10⁵ to appear is usually overflow or a time limit, and you’ll find those by reading the constraints again.
Online assessments hide their tests too, so the same habit pays off there. A two-minute check against a brute force catches the cases the samples skip.
