> ## Documentation Index
> Fetch the complete documentation index at: https://resources.devweekends.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Debugging & Stress Testing

> Find bugs faster—systematic debugging and stress testing for competitive programming

# Debugging & Stress Testing

## The Cost of Debugging in CP

Every minute spent debugging is a minute not solving the next problem. Learn to debug fast.

```
┌─────────────────────────────────────────────────────┐
│         TIME COST OF BUGS IN CONTEST                │
├─────────────────────────────────────────────────────┤
│  Wrong Answer (WA)                                  │
│    - Finding bug: 3-10 minutes                      │
│    - Penalty: varies by scoring system (see below)  │
│    - Total: significant time lost                   │
│                                                     │
│  Time Limit Exceeded (TLE)                          │
│    - Rethinking approach: 5-15 minutes              │
│    - Rewriting: 5-10 minutes                        │
│    - Total: 10-25 minutes lost                      │
└─────────────────────────────────────────────────────┘
```

<Note>
  **Contest Scoring Systems on Codeforces**:

  **ICPC Rules** (most Div 2/3/4 contests):

  * Each wrong submission adds **+10 minute penalty**
  * Final score = time of AC + (10 × wrong attempts)
  * Earlier solve = better rank

  **IOI Rules** (Educational rounds, some special contests):

  * Partial scoring based on test cases passed
  * No time penalty for wrong submissions
  * Score = points earned (not time-based)
  * Maximum points per problem (e.g., 100, 250, 500, etc.)

  **Codeforces Scoring** (standard Div 1/2 rounds):

  * Points decrease over time (max points at start)
  * Each wrong submission costs **-50 points** (before AC)
  * No penalty after AC
</Note>

***

## Prevention > Debugging

### Before You Code

<Steps>
  <Step title="Understand the Problem Completely">
    Re-read after you think you understand. Check examples manually.
  </Step>

  <Step title="Plan Your Approach">
    Think through edge cases before coding.
  </Step>

  <Step title="Choose Data Types Carefully">
    Will values overflow `int`? Use `long long` proactively.
  </Step>

  <Step title="Write Clean Code">
    Use meaningful variable names. Keep functions small.
  </Step>
</Steps>

### Common Bug Prevention

```cpp theme={null}
// Use these by default
#define int long long  // Prevent overflow

// Check array bounds explicitly
if (i >= 0 && i < n && j >= 0 && j < m) {
    // Safe to access grid[i][j]
}

// Initialize variables
int sum = 0;  // Not just: int sum;

// Use const for array sizes
const int N = 2e5 + 5;
int arr[N];
```

***

## Systematic Debugging Process

### Step 1: Read the Verdict

| Verdict | First Action                              |
| ------- | ----------------------------------------- |
| **WA**  | Check edge cases, trace smallest example  |
| **TLE** | Check complexity, look for infinite loops |
| **RE**  | Check bounds, division by zero            |
| **MLE** | Check array sizes, recursive depth        |

### Step 2: Test Edge Cases

Always test these inputs:

```cpp theme={null}
// Minimum cases
n = 1
n = 0 (if allowed)
empty input

// Boundary cases
All same values
All different values
Maximum constraints
Minimum values (0, 1, -1)

// Special patterns
Sorted ascending
Sorted descending
Alternating pattern
```

### Step 3: Trace Through by Hand

For small inputs, trace your code step by step:

```cpp theme={null}
// For input: n=3, arr=[1, 2, 3]
// Trace each line:
// i=0: sum=0+1=1
// i=1: sum=1+2=3
// i=2: sum=3+3=6
// Output: 6 ✓
```

### Step 4: Add Debug Output

```cpp theme={null}
#ifdef LOCAL
#define debug(x) cerr << #x << " = " << x << endl
#else
#define debug(x)
#endif

// Usage
int ans = calculate(n);
debug(ans);  // Only prints when compiled with -DLOCAL
```

***

## Common Bug Patterns

### Integer Overflow

```cpp theme={null}
// BUG: Overflow in multiplication
int a = 100000, b = 100000;
int product = a * b;  // Overflow!

// FIX: Use long long
long long product = (long long)a * b;

// Or use #define
#define int long long
```

### Off-by-One Errors

```cpp theme={null}
// BUG: Accessing arr[n] (out of bounds)
for (int i = 0; i <= n; i++) {
    arr[i] = 0;  // When i=n, this is out of bounds!
}

// FIX: Use < instead of <=
for (int i = 0; i < n; i++) {
    arr[i] = 0;
}
```

### Uninitialized Variables

```cpp theme={null}
// BUG: Using uninitialized variable
int count;
for (int x : arr) {
    if (x > 0) count++;  // count is garbage!
}

// FIX: Initialize
int count = 0;
```

### Array Index Errors

```cpp theme={null}
// BUG: 1-indexed vs 0-indexed confusion
for (int i = 1; i <= n; i++) {
    cin >> arr[i];  // Works if arr has size n+1
}
// Later...
for (int i = 0; i < n; i++) {
    // arr[i] has garbage for i=0!
}

// FIX: Be consistent, prefer 0-indexed
```

### Multiple Test Case Issues

```cpp theme={null}
// BUG: Not resetting between test cases
int globalCounter = 0;
vector<int> seen;

void solve() {
    // globalCounter and seen retain old values!
}

// FIX: Reset at start of each test case
void solve() {
    int counter = 0;  // Local variable
    vector<int> seen; // Fresh vector
    // Or explicitly clear: seen.clear();
}
```

### Floating Point Comparison

```cpp theme={null}
// BUG: Direct floating point comparison
double a = 0.1 + 0.2;
if (a == 0.3) {  // This is FALSE!
    // ...
}

// FIX: Use epsilon comparison
const double EPS = 1e-9;
if (abs(a - 0.3) < EPS) {
    // ...
}
```

***

## Debug Macros Template

Add this to your template:

```cpp theme={null}
#ifdef LOCAL
    #define debug(x) cerr << "[" << #x << " = " << (x) << "]" << endl
    #define debugv(v) { cerr << "[" << #v << ": "; for(auto& x : v) cerr << x << " "; cerr << "]" << endl; }
    #define debugm(m) { cerr << "[" << #m << "]:" << endl; for(auto& row : m) { for(auto& x : row) cerr << x << " "; cerr << endl; } }
#else
    #define debug(x)
    #define debugv(v)
    #define debugm(m)
#endif

// Usage:
int n = 5;
debug(n);  // Prints: [n = 5]

vector<int> arr = {1, 2, 3};
debugv(arr);  // Prints: [arr: 1 2 3]

vector<vector<int>> grid = {{1,2},{3,4}};
debugm(grid);  // Prints 2D grid
```

Compile with `-DLOCAL` to enable debug output:

```bash theme={null}
g++ -DLOCAL -o solution solution.cpp
```

***

## Stress Testing

### What is Stress Testing?

Stress testing = Running your solution against a brute force on random inputs until they disagree.

```
┌─────────────────────────────────────────────────────┐
│              STRESS TEST FLOW                       │
├─────────────────────────────────────────────────────┤
│  1. Write brute force solution (slow but correct)   │
│  2. Write optimized solution (fast but buggy?)      │
│  3. Generate random test case                        │
│  4. Run both solutions                               │
│  5. Compare outputs                                  │
│  6. If different → found the bug!                   │
│  7. Repeat until confident                           │
└─────────────────────────────────────────────────────┘
```

### Complete Stress Test Setup

**File 1: solution.cpp** (your optimized code)

```cpp theme={null}
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> arr(n);
    for (int& x : arr) cin >> x;
    
    // Your optimized solution
    int ans = 0;
    // ...
    
    cout << ans << endl;
    return 0;
}
```

**File 2: brute.cpp** (simple correct solution)

```cpp theme={null}
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    cin >> n;
    vector<int> arr(n);
    for (int& x : arr) cin >> x;
    
    // Brute force O(n²) or O(n³) - slow but correct
    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = i; j < n; j++) {
            // Check every possibility
        }
    }
    
    cout << ans << endl;
    return 0;
}
```

**File 3: gen.cpp** (random test generator)

```cpp theme={null}
#include <bits/stdc++.h>
using namespace std;

int main(int argc, char* argv[]) {
    mt19937 rng(atoi(argv[1]));  // Seed from command line
    
    int n = rng() % 10 + 1;  // n from 1 to 10 (small for stress)
    cout << n << endl;
    
    for (int i = 0; i < n; i++) {
        cout << (rng() % 100 + 1);  // values from 1 to 100
        if (i < n-1) cout << " ";
    }
    cout << endl;
    
    return 0;
}
```

**File 4: stress.bat** (Windows)

```batch theme={null}
@echo off
g++ -O2 solution.cpp -o solution.exe
g++ -O2 brute.cpp -o brute.exe
g++ -O2 gen.cpp -o gen.exe

for /L %%i in (1,1,1000) do (
    gen.exe %%i > input.txt
    solution.exe < input.txt > output1.txt
    brute.exe < input.txt > output2.txt
    fc output1.txt output2.txt > nul
    if errorlevel 1 (
        echo Test %%i FAILED!
        type input.txt
        echo Solution output:
        type output1.txt
        echo Brute output:
        type output2.txt
        exit /b 1
    )
    echo Test %%i passed
)
echo All tests passed!
```

**File 4: stress.sh** (Linux/Mac)

```bash theme={null}
#!/bin/bash
g++ -O2 solution.cpp -o solution
g++ -O2 brute.cpp -o brute
g++ -O2 gen.cpp -o gen

for i in $(seq 1 1000); do
    ./gen $i > input.txt
    ./solution < input.txt > output1.txt
    ./brute < input.txt > output2.txt
    if ! diff -q output1.txt output2.txt > /dev/null; then
        echo "Test $i FAILED!"
        echo "Input:"
        cat input.txt
        echo "Solution output:"
        cat output1.txt
        echo "Brute output:"
        cat output2.txt
        exit 1
    fi
    echo "Test $i passed"
done
echo "All tests passed!"
```

***

## Quick Debug Checklist

When you get WA, check in this order:

<Steps>
  <Step title="Did I read the problem correctly?">
    Re-read problem statement. Check constraints again.
  </Step>

  <Step title="Integer overflow?">
    Use `long long` for any multiplication or large sums.
  </Step>

  <Step title="Edge cases?">
    Test n=1, n=0, all same, all different.
  </Step>

  <Step title="Off-by-one?">
    Check loop bounds, array indexing.
  </Step>

  <Step title="Uninitialized variables?">
    Check all variables are initialized.
  </Step>

  <Step title="Multiple test cases?">
    Are you resetting everything between cases?
  </Step>

  <Step title="Output format?">
    Spaces, newlines, YES vs Yes vs yes?
  </Step>
</Steps>

***

## Debugging Different Verdicts

### Wrong Answer (WA)

1. Test all examples manually
2. Create small custom test
3. Check edge cases
4. Add debug output
5. Stress test if needed

### Time Limit Exceeded (TLE)

1. Check complexity analysis
2. Look for accidental O(n²) operations
3. Check for infinite loops
4. Use faster I/O if not already
5. Consider algorithm change

```cpp theme={null}
// Common hidden O(n²):
for (int i = 0; i < n; i++) {
    string s = str.substr(i);  // O(n) each time!
}

// Fix: Avoid creating substrings
```

### Runtime Error (RE)

1. Check array bounds
2. Check division by zero
3. Check stack overflow (deep recursion)
4. Check null pointer / empty container

```cpp theme={null}
// Common RE causes:
arr[n];     // Out of bounds (0-indexed)
x / y;      // y might be 0
vec.back(); // vec might be empty
*ptr;       // ptr might be null
```

### Memory Limit Exceeded (MLE)

1. Check array sizes
2. Avoid unnecessary copies
3. Use iterative instead of recursive
4. Use memory-efficient data structures

```cpp theme={null}
// MLE causes:
int arr[1000000000];  // Too big!
vector<vector<int>> adj(n, vector<int>(n));  // O(n²) memory

// Fixes:
vector<int> arr(n);  // Dynamic allocation
vector<vector<int>> adj(n);  // Adjacency list
```

***

## Pro Debugging Tips

### Print and Exit

When stuck on one test case:

```cpp theme={null}
// Find which test case fails
int caseNum = 0;
while (t--) {
    caseNum++;
    // If answer should be X for case 5:
    if (caseNum == 5) {
        cerr << "Debug case 5" << endl;
        debug(n);
        debugv(arr);
    }
    solve();
}
```

### Binary Search on Test Cases

If failing on test case 50 out of 100:

```cpp theme={null}
// Skip first 49 cases
int skip = 49;
while (t--) {
    if (skip > 0) {
        skip--;
        // Read input but don't process
        int n; cin >> n;
        // ... discard ...
        continue;
    }
    solve();  // Only solve case 50
}
```

### Assert for Assumptions

```cpp theme={null}
#include <cassert>

void solve(int n) {
    assert(n >= 1 && n <= 100000);  // Crash if invalid
    // ...
}
```

***

## Key Takeaways

<CardGroup cols={2}>
  <Card title="Prevention First" icon="shield">
    Use safe defaults: `long long`, initialize variables, check bounds.
  </Card>

  <Card title="Systematic Process" icon="list-check">
    Follow a checklist. Don't randomly try fixes.
  </Card>

  <Card title="Debug Macros" icon="code">
    Have debug macros ready in your template.
  </Card>

  <Card title="Stress Test" icon="vial">
    When stuck, stress test against brute force.
  </Card>
</CardGroup>

***

## Next Steps

<Card title="Environment Setup" icon="gear" href="/courses/competitive-programming/02a-environment-setup">
  Set up VS Code with tasks for stress testing.
</Card>
