Skip to main content
  1. Posts/

I went looking for AI-resistant CS1 problems. The search came up empty.

··1248 words·6 mins·
Nick Liu
Author
Nick Liu
Building infrastructure for Facebook Feed Ranking at Meta. Previously at Walmart, Twitter, AWS, and eBay. MS in Computer Science at Georgia Tech.
Table of Contents
Auditing AI-Solvability - This article is part of a series.
Part 1: This Article
For six weeks this summer I hunted for a CS1 programming problem that an AI model could not solve. I found exactly one candidate. It scored 0.00 against the weaker model, the stronger model solved it, and my fairness checks came back clean. Then I reworded the problem statement in plain English, changed nothing about the hidden tests, and the resistance evaporated.

What I was measuring
#

The tool is called cs1-auditor. It is a Python command-line tool that audits how solvable one CS1 problem is for a named model. You point it at a problem folder holding a plain-English spec, a hidden test suite, and a reference solution. It samples N candidate solutions from the model, runs each one in a sandbox against the hidden tests, and reports two things. The first is an AI-solvability score, which is pass@k for that model on that date. The second is a construct check, which asks whether any resistance comes from a real skill or from a trick in the wording. A problem only earns the label AI-resistant when the score is below a threshold and the construct check is clean.

Defaults: 20 samples per audit, pass@k reported at k=1 and k=5, threshold 0.2. The pass@k estimator is the unbiased one from the Codex paper, not the naive “did any of the first k pass”.

yes

no

problem folder
spec + hidden tests + reference

model
samples N=20 solutions

pre-flight
reference vs hidden tests

sandbox
each candidate vs hidden tests

pass@k score
k=1, k=5

construct check
4 offline fairness rules

score < 0.2
AND clean?

AI-RESISTANT

AI-SOLVABLE

yes

no

problem folder
spec + hidden tests + reference

model
samples N=20 solutions

pre-flight
reference vs hidden tests

sandbox
each candidate vs hidden tests

pass@k score
k=1, k=5

construct check
4 offline fairness rules

score < 0.2
AND clean?

AI-RESISTANT

AI-SOLVABLE

The scale of the evidence, so you can weigh it: I authored 58 problems, ran 34 of them against live models, and collected 1,095 sampled solutions between 2026-06-14 and 2026-07-23. Four model versions, all from one vendor: claude-sonnet-4-6, claude-haiku-4-5, claude-haiku-4-5-20251001, and claude-sonnet-4-5-20250929. One rater, one vendor, one summer. Every claim below sits inside that box.

The one candidate
#

Most problems never got close to resistant. On six clean baseline problems, the strong model went 1.00 across the board and the weak model slipped on only two (0.75 on a conditionals problem, 0.60 on a rounding problem). Five problems built around a non-default rule did better at separating the models, and one stood out:

ProblemThe non-default ruleSonnetHaiku
count-multiples-01closed range, negative bounds1.000.00

Haiku produced twenty candidate solutions and zero passed. Sonnet solved it every time. The construct check came back clean: the skill was declared, the spec was plain ASCII, no tricks. The tool printed the label I had been chasing: AI-RESISTANT (construct-valid).

The reword protocol
#

A low score can mean the problem tests a real skill the model lacks. It can also mean the model tripped on the phrasing. To tell these apart I added a fifth check that is a protocol rather than a rule: reword the spec in plain English, keep the hidden tests byte-for-byte identical, and audit again. If the resistance is real, it should survive a paraphrase.

ProbeHaiku pass@1Outcome
count-multiples-01 (baseline)0.00AI-RESISTANT (construct-valid)
reword 10.00resistance held
reword 20.75flipped to AI-SOLVABLE

The second paraphrase lifted Haiku from 0.00 to 0.75. Same tests. Same skill, supposedly. Sonnet solved the baseline and both rewords at 1.00 throughout. Whatever count-multiples-01 was measuring, it was not a stable property of the task. It was a property of one particular arrangement of words, on one model, on one date.

The score itself would not sit still
#

One more honesty requirement before the big claim. The 0.00 comes from the 20-attempt run of 16 July. I reran the same baseline problem on later dates:

DateAttemptsPassedpass@1
2026-07-162000.00
2026-07-172010.05
2026-07-18510.20

So I will not write that Haiku failed it every single time. It scored 0.00 on the run I reported, and drifted to 0.05 and 0.20 on repeats. At first this annoyed me. Then I realized it is a second argument for the same thesis: even the score of one fixed problem moves between runs, so a single number pinned to a task is not a stable property. It is a measurement of a model, on a date, with a sample size attached. My tool stamps every record with all three, and this is why.

Widening the search#

Maybe count-multiples-01 was unlucky and better candidates existed. I ran two more batches, 13 fresh problems designed around non-default rules. The bar for a keeper: fair by the construct check, solved by the strong model, failed by the weak model, and still failing after a reword. Not one problem cleared all four.

The most instructive failure was slice-1based-01. Haiku scored 0.15, which looked promising, but Sonnet also failed it at 0.00. A problem both models fail is not a resistant problem. It is a badly specified one. Its rewords lifted Haiku to 0.40 and 0.20, which fits the pattern: the difficulty lived in the wording.

Why the search may be structurally empty
#

The pattern generalizes into a tension I could not find a way around.

To be fair, and to be solvable by a strong model, the twist in a problem must be stated clearly. But a clearly stated twist is one that the weakest model you can still realistically use also reads. The genuinely weak models that a resistant problem would need have been retired. So the skill gap that resistance depends on has closed, at least for CS1, at least for the models I tested.

This does not mean no AI-resistant assessment can exist anywhere. It means that within my box (one vendor, four model versions, six weeks, 58 authored problems, 1,095 attempts) every candidate either failed the fairness bar or failed the reword. Prior work found GPT-4 passing about 95 percent of textbook CS1 tasks, so the ceiling was known to be high before I started. What I did not expect is how completely the floor had risen too.

Lessons
#

  • A low pass@k is a claim about wording until a paraphrase has failed to fix it. Reword first, then talk about skill gaps.
  • Report the run you measured, with its date and sample size. My “0.00” became 0.05 and 0.20 on later runs of the identical problem.
  • A problem that every model fails is not resistant. It is broken. Check the strong model before celebrating the weak model’s failure.
  • If a resistant problem needs an unclearly stated twist to work, the resistance is construct-irrelevant variance, not a skill.

The next post in this series is about the part of the tool that made these numbers trustworthy in the first place: the harness, and the three rules that kept 1,095 sandbox runs from lying to me.

References
#

Auditing AI-Solvability - This article is part of a series.
Part 1: This Article

Related

I hid zero-width characters in a CS1 spec. The model did not blink.

··994 words·5 mins
I made two sabotaged copies of a CS1 problem. Into the first I inserted zero-width characters, invisible in any editor. Into the second I went heavier and swapped letters for Unicode look-alikes as well. The hidden tests stayed byte-for-byte identical. If obfuscation works as an AI defense, the model's score should drop. It scored 0.85 on both copies. The attack did nothing. My fairness check flagged both copies anyway, and that second part is the one worth writing about. Auditing AI-Solvability · Part 4 of 5 1 2 3 4 5 Why sabotage my own problem # Instructors keep looking for ways to make assignments that AI tools fail. One family of ideas is to leave the problem alone and poison the text: invisible characters, homoglyphs, formatting tricks that a human reader never notices but that might derail a model reading the same bytes. Before trusting any resistance my tool (part 1) reported, I needed to know what this kind of tampering does to a score, because a problem that scores low for wording reasons is fake difficulty, not a real skill gap.

Cohen's kappa came back 0.00. The agreement was 6 out of 8.

··1028 words·5 mins
I labelled eight CS1 problems blind, before looking at any output from my auditing tool. Then I compared my labels with the tool's verdicts. We agreed on 6 of 8. Then I computed Cohen's kappa, the standard chance-corrected agreement statistic, and it printed 0.00. Exactly zero, sitting next to a 75 percent raw agreement. My first thought was that my code was broken. It was not. Auditing AI-Solvability · Part 3 of 5 1 2 3 4 5 The setup # This was the human-agreement check for the tool from part 1. The tool labels each problem AI-solvable or AI-resistant. For the check to mean anything, my own labels had to be committed before I saw the tool’s, so I wrote them down blind, sealed against hindsight. Eight problems, two raters: me and the tool.

Finding the Bottom of a Valley Blindfolded: Understanding Gradient Descent

··1326 words·7 mins
Imagine you're **blindfolded on a mountain** and you need to find the lowest valley. You can't see anything, but you *can* feel the ground under your feet. What would you do? You'd feel which direction slopes downward, take a small step that way, and repeat. Congratulations. You just invented **gradient descent**, the algorithm behind nearly every modern AI system. ML Fundamentals · Part 1 of 3 1 2 3 Why Should You Care? # Optimization is everywhere. When your GPS finds the fastest route, when Netflix recommends a movie, when your phone recognizes your face, behind all of these is an algorithm trying to find the best possible answer from a sea of possibilities. Gradient descent is the workhorse algorithm that makes this happen.