Automated Correctness Checking Using Random Input and Brute Force Oracles

A common technique to catch logical errors in a efficient algorithm is to compare its output against a slower brute-force implementation on many small, random generated test cases. The setup below uses the least common multiple (LCM) of two integers as the target problem.

Scripts and their roles

All components are implemented as standalone Python scripts. No compilation step is required.

1. Input generator (gen.py)

Generates a single line containing two space-separated integers, each in the range [1, 200]. Small bounds keep the brute-force execution fast.

import random
import sys

def generate():
    a = random.randint(1, 200)
    b = random.randint(1, 200)
    sys.stdout.write(f"{a} {b}\n")

if __name__ == "__main__":
    generate()

2. Brute-force reference (brute.py)

Reads the two integers and computes the LCM by scanning from max(a, b) upwards until a common multiple is found.

import sys

def solve():
    data = sys.stdin.read().strip().split()
    if not data:
        return
    x, y = map(int, data[:2])
    start = x if x > y else y
    end = x * y
    for val in range(start, end + 1):
        if val % x == 0 and val % y == 0:
            sys.stdout.write(str(val))
            return

if __name__ == "__main__":
    solve()

3. Optimised solution (solution.py)

Uses the relationship lcm(a, b) = a // gcd(a, b) * b. The GCD is computed with the Euclidean algorithm.

import sys
from math import gcd

def solve():
    data = sys.stdin.read().strip().split()
    if not data:
        return
    x, y = map(int, data[:2])
    result = x // gcd(x, y) * y
    sys.stdout.write(str(result))

if __name__ == "__main__":
    solve()

4. Test harness (check.py)

Runs the generator, pipes the same input into both brute.py and solution.py, cpatures their outputs, and flags any difference.

import subprocess
import sys

TEST_COUNT = 200

def main():
    for i in range(1, TEST_COUNT + 1):
        gen = subprocess.run(["python3", "gen.py"],
                             capture_output=True, text=True)
        sample_input = gen.stdout

        ref = subprocess.run(["python3", "brute.py"],
                             input=sample_input,
                             capture_output=True, text=True)
        opt = subprocess.run(["python3", "solution.py"],
                             input=sample_input,
                             capture_output=True, text=True)

        ref_out = ref.stdout.strip()
        opt_out = opt.stdout.strip()

        if ref_out != opt_out:
            print(f"Mismatch on test #{i}:")
            print(f"  input: {sample_input.strip()}")
            print(f"  brute output: {ref_out}")
            print(f"  optimized output: {opt_out}")
            sys.exit(1)

    print(f"All {TEST_COUNT} tests passed.")

if __name__ == "__main__":
    main()

Tips for usage

  • Pre-compile or keep scripts ready; avoid running build steps inside the test harness.
  • Keep random inputs small so the brute-force algorithm finishes quickly.
  • Pair testing guarantees correctness for the tested inputs, not algorithmic optimality.

Tags: pair testing random test generation lcm brute force Competitive Programming

Posted on Thu, 27 Aug 2026 16:32:52 +0000 by BinaryStar