DEV Community

Cover image for Debug For Competitive Programming πŸ›
Deepak
Deepak

Posted on

Debug For Competitive Programming πŸ›

DEV Weekend Challenge: Passion Edition Submission

This is a submission for Weekend Challenge: Passion Edition

Debug App

An AI-powered differential debugger for competitive programming

I built Debug App from a very real frustration I face while solving coding problems.

Imagine this: you are solving a problem on Codeforces or a similar platform. You write your code, test it on the sample inputs given in the statement, and everything looks fine. You submit with confidence… and the verdict comes back: Wrong Answer.

Now the actual struggle begins.

Your code is failing on some hidden internal testcase, but you do not know which one. At the same time, your friend solved the same problem and got Accepted, so you know the issue is somewhere in your logic. The next step is debugging β€” and debugging itself is not the problem. In fact, debugging is an important part of learning. The difficult part is finding a good testcase that actually exposes the bug.

Sometimes that testcase is easy to spot. But many times, especially in competitive programming, the bug appears only on a very specific edge case: a corner condition, a duplicate-heavy input, a boundary value, a strange ordering, or a case that you simply did not think of. Finding that one failing input can take much longer than expected.

So naturally, the next idea is: β€œwhy not ask AI for a failing testcase?”

That sounds good in theory, but in practice, normal AI often struggles here. It may confidently suggest a testcase, but when you actually run the code on that input, both versions produce the same output. Then when you tell it that the testcase does not fail, it responds with something like: β€œYou are right, let me give another testcase.” At that point, the weakness becomes obvious: the model is guessing, not verifying.

That is exactly why I built Debug App.

Instead of only suggesting what might fail, Debug App takes a stronger approach: it tests both codes, checks whether the outputs actually differ, confirms the failing testcase, and only then moves to diagnosis. The goal is to turn debugging from a guessing game into a verified workflow.

Demo

What I Built

Debug App is an AI-powered differential debugger for competitive programming.

The core idea is simple: if one solution is buggy and another correct solution is accepted, then there must exist some input on which they behave differently. So instead of asking AI to β€œjust guess the bug,” I built a system that uses both reasoning and verification.

The user pastes:

  • their buggy code
  • a correct reference solution

From there, the app:

  • detects the programming language
  • analyzes the problem structure
  • checks for syntax issues
  • generates adversarial or edge-case inputs
  • runs both codes on those testcases
  • compares the outputs
  • identifies an actual failing testcase
  • explains the likely bug and suggests a fix

The app also includes a custom single-test runner, AI chat for debugging follow-ups, and full debug history so users can revisit previous sessions.

This makes the experience much more useful than a normal chatbot conversation, because the debugging is grounded in actual execution rather than only text-based reasoning.

The problem it solves

The real pain point in competitive programming is often not writing the initial solution β€” it is finding the exact testcase where your logic breaks.

A lot of developers use two separate tabs or windows for this process:

  • one tab to run their buggy solution
  • another tab to run a correct version
  • then manually copy the same input into both places
  • compare outputs line by line
  • go back and try again

That works, but it is slow and repetitive.

I wanted a workflow where both codes could be compiled and tested at the same place, on the same input, with the result immediately visible. Once that part becomes easy, debugging becomes much more focused.

Debug App is designed around exactly that need.

How the app works

1. Paste both codes

The workflow starts by providing two versions of the solution:

  • the buggy implementation
  • the correct reference implementation

This is the foundation of the app. Instead of debugging in isolation, the tool uses comparison as the main strategy.

2. Analyze before testing

Before execution, the app uses AI to understand the code and infer the structure of the problem. It tries to detect the language, understand likely input/output format, and reason about what kind of edge cases may reveal the issue.

This matters because random testcase generation is often not enough. The tool should generate testcases with intent.

3. Find the failing testcase

This is the most important feature of the project.

Instead of just saying β€œyour code might fail on edge cases,” the app actively tries to find one testcase that really fails. It generates candidate testcases, executes both codes, and keeps checking whether the outputs differ.

That verification step is what makes the workflow reliable.

If both codes behave the same way, then that testcase is not useful. If the outputs differ, then the app has found something valuable: a confirmed failing testcase that the user can inspect and learn from.

This is especially useful for bugs involving:

  • boundary conditions
  • off-by-one errors
  • mishandled duplicates
  • wrong assumptions about sorted order
  • integer overflow or type issues
  • missed corner cases in loops or conditionals

4. Run both codes at the same place

This is another feature I cared about a lot.

Usually, if I want to compare outputs manually, I have to use separate tabs, separate compilers, or repeated copy-paste. That creates unnecessary friction.

So I built a feature where the user can provide a custom input and run both codes at the same place. The app executes both versions side by side and shows the outputs together.

This makes comparison much easier because:

  • the input is shared
  • the outputs are visible together
  • the mismatch becomes obvious immediately
  • there is no need to keep switching contexts

It sounds like a small convenience feature, but for real debugging it saves a surprising amount of time.

5. Diagnose the bug with AI

Once an actual mismatch is confirmed, the app moves to diagnosis.

At this point, AI becomes much more useful because it is no longer working from a vague prompt. It already has:

  • both code versions
  • the failing testcase
  • the execution results
  • the exact mismatch

That gives it a much stronger base for explanation.

The diagnosis stage tries to identify:

  • the likely root cause
  • the line or logic area involved
  • the reason the bug appears
  • the kind of change that would fix it

This is much more practical than generic advice, because the explanation is tied to a real failing case rather than guesswork.

Features

Find failing testcases automatically

This is the headline feature. The app generates adversarial inputs and verifies them through execution until it finds a testcase that actually exposes the difference.

Compare both codes on one input

The single-test runner lets users run both solutions on the same custom input in one place. That removes the need to use multiple tabs or external compilers just to compare outputs.

AI-powered bug diagnosis

After the mismatch is confirmed, the app explains the likely bug, root cause, and possible fix. This turns raw output difference into actionable debugging help.

AI chat for debugging follow-up

Debugging is rarely finished after one answer. Often the next question is:

  • why exactly did this testcase fail?
  • is my fix correct?
  • what other edge cases should I try?

That is why I added a context-aware AI chat assistant for each debugging session.

This makes the app feel less like a one-time analyzer and more like a debugging companion.

Debug history

Every debug session is saved for up to three months with important details:

  • code versions
  • generated testcase
  • outputs
  • diagnosis
  • chat context

This is useful because debugging patterns repeat. Looking back at old mistakes can actually help programmers improve their thinking over time.

Syntax and runtime detection

Before deeper analysis, the app also checks for syntax or runtime issues. That prevents unnecessary debugging effort when the problem is simply that the code does not compile or crashes early.

Responsive UI with dark/light mode

The interface is designed to be clean and developer-focused across devices, from desktop to mobile.

How I Built It

Frontend

The frontend is built with:

  • React + Vite
  • Bootstrap
  • Monaco Editor
  • Lucide React

Monaco Editor was a natural choice because it gives a coding experience that feels familiar and professional. Since the product is aimed at programmers, the editor experience had to feel strong.

Backend

The backend is built with:

  • Node.js
  • Express
  • PostgreSQL (Neon)

I used this stack to support the debugging pipeline, session storage, authentication, chat context, and history persistence.

Authentication and session management

To make the app feel complete, I added:

  • Passport.js with Google OAuth
  • express-session
  • connect-pg-simple

That allows users to log in, save sessions, and return to their debugging history later.

AI and execution pipeline

This is the heart of the project.

For AI:

  • NVIDIA Nemotron for reasoning and testcase generation
  • NVIDIA Llama 3.1 8B for syntax checks and chat
  • NVIDIA Nemotron Super 49B for bug diagnosis

For execution:

  • Judge0
  • Judge0 fallback
  • OnlineCompiler.io

One thing I especially wanted to solve was reliability. Code execution APIs can fail, timeout, or behave inconsistently, so I built a fallback-based execution setup. That means the app is not dependent on a single code runner.

This was important because if the goal is to verify failing testcases, then execution reliability is not optional β€” it is central to the product.

Why this project is personal

This project is directly connected to how I practice coding.

As someone who spends time solving problems and improving in competitive programming, I wanted to build something that solves a real difficulty I face. I did not want to make a generic β€œAI coding assistant.” I wanted to make a focused tool for a specific workflow: finding the testcase, verifying the mismatch, and understanding the bug.

That focus is what makes Debug App special to me.

It respects the fact that debugging is part of learning, but it tries to reduce the unproductive part β€” the repeated trial-and-error of finding the right failing input and comparing outputs manually.

What’s next

There is still a lot of room to improve this idea further. Some directions I would like to explore are:

  • better testcase generation strategies
  • more language support
  • richer diff visualization
  • stronger explanation quality for diagnosis
  • tighter integration with contest workflows

But even in its current form, Debug App already solves a problem I genuinely care about.

Prize Categories

This is a general submission for the Weekend Challenge: Passion Edition.

Closing thoughts

Debug App started from a simple but frustrating scenario: my code fails on a hidden testcase, the sample tests all pass, and I need to figure out where the logic breaks.

Traditional AI can help with ideas, but for complex debugging it often stops short of what really matters: verification.

That is the gap I wanted to close.

So instead of only asking AI to reason, I built a workflow where AI can reason and the system can test. The result is a debugging tool that helps find actual failing testcases, compare both codes in one place, and turn wrong answers into something understandable.

For a project built around passion, this felt like the right one to make.

Top comments (0)