Содержание
Нейросети уверенно пишут программы. Но насколько этим программам можно верить, если задача — обычная учебная, а спрашивает начинающий? Мы проверили это на практике: взяли десять задач уровня первых месяцев обучения, в каждую заложили типичную ловушку и попросили три модели написать решение на C++.
Результат оказался не таким, как мы ожидали, и вывод из него полезнее, чем «нейросеть ошибается» или «нейросеть не ошибается».
Как устроен эксперимент
Модели. Три модели, подключённые к песочнице нашего курса: GPT-6 Luna (лёгкая), Claude 5.5 Sonnet и GPT-6.1 Sol. Запросы отправлялись 10 октября 2026 года, без системного промпта, по одному разу на каждую пару «модель — промпт».
Задачи. Десять задач, в каждой — ловушка, на которую попадаются новички.
| Задача | Ловушка |
|---|---|
| Сумма N чисел | сумма не помещается в int |
| Максимум из чисел до конца ввода | все числа отрицательные; чисел нет вовсе |
| Сколько различных чисел | двойной цикл не успевает при N = 200 000 |
| Среднее с двумя знаками после запятой | целочисленное деление |
| Неотрицательный остаток от деления | в C++ -7 % 3 равно -1 |
| НОК двух чисел до 10^18 | произведение переполняет 64 бита |
| Простое ли число до 10^12 | единица, квадрат простого, переполнение i * i, перебор до N |
| Первый элемент массива не меньше x | линейный поиск не успевает; ошибка на единицу |
| Високосный год | годы, кратные 100 и 400 |
| Палиндром в строке с пробелами | cin >> s читает только первое слово |
Две формулировки. Каждую задачу мы задавали дважды. Первый раз — полным условием, как в задачнике:
Дано число N (1 ≤ N ≤ 100000), затем N целых чисел, каждое по модулю
не больше 10^9. Выведите их сумму.
Напиши программу на C++17. Ввод — со стандартного ввода, вывод —
в стандартный вывод.
Второй раз — так, как обычно спрашивает ученик:
Напиши программу на C++: вводится N и потом N целых чисел, надо вывести
их сумму.
Проверка. Из каждого ответа мы брали код, компилировали его g++ 14.2 с флагами -O2 -std=c++17 и запускали на тестах с ограничением две секунды. Всего 53 теста, среди них — крайние случаи и большие входные данные. Вывод сравнивался с эталоном автоматически. Один тест — пустой ввод в задаче о максимуме — применялся только к полному условию: в коротком промпте не сказано, что выводить, если чисел нет.
Итого 60 решений: 10 задач × 2 формулировки × 3 модели.
Результат: полное условие
| Модель | Задач решено |
|---|---|
| GPT-6 Luna | 10 из 10 |
| Claude 5.5 Sonnet | 10 из 10 |
| GPT-6.1 Sol | 10 из 10 |
Все тридцать решений прошли все тесты. Ни одна ловушка не сработала: сумма считалась в long long, остаток приводился к неотрицательному, простота проверялась перебором до корня, а поиск в массиве был двоичным.
Результат: короткий промпт
| Модель | Прошли тесты | Не прошли |
|---|---|---|
| GPT-6 Luna | 9 из 10 | поиск в массиве |
| Claude 5.5 Sonnet | 8 из 10 | поиск в массиве, НОК |
| GPT-6.1 Sol | 9 из 10 | поиск в массиве |
Четыре решения из тридцати тесты не прошли. Но ни в одном из них нет ошибки в алгоритме.
Поиск в массиве: модели угадывали формат ввода
Короткий промпт звучал так: «дан отсортированный массив из N чисел и Q запросов». В каком порядке идут числа во входных данных, сказано не было. В наших тестах сначала записано N, потом массив, потом Q, потом запросы. Все три модели решили иначе: N и Q в первой строке.
int N, Q;
cin >> N >> Q;
Программа читает первое число массива как Q и дальше выводит бессмыслицу. Мы переставили числа во входном файле так, как ожидали модели, — и все три решения прошли самый большой тест: сто тысяч запросов к массиву из ста тысяч чисел. Алгоритм верный, двоичный поиск на месте.
Отличались модели другим. Claude 5.5 Sonnet и GPT-6.1 Sol написали под кодом, какой формат ввода они предположили; Sonnet добавила: «Если в вашей задаче другой формат ввода, поправьте считывание». GPT-6 Luna о своём предположении не сказала ничего.
НОК: программа разговаривает с пользователем
Claude 5.5 Sonnet на короткий промпт написала программу для человека, а не для проверяющей системы:
Введите два натуральных числа: НОК(4, 6) = 12
Число верное, включая случай с двумя числами по 10^18: деление выполняется раньше умножения. Но автоматическая проверка ждёт в выводе только 12 и такое решение не засчитает. В промпте не было сказано, кто будет читать вывод, — и модель выбрала вариант «для человека».
Приёмы, которые стоит перенять
Короткий промпт не называл ограничений, но модели всё равно писали осторожно. Во всех трёх решениях задачи о сумме стоит long long, хотя про размер чисел не было ни слова.
GPT-6.1 Sol при проверке простоты написала условие цикла так, чтобы произведение не могло переполниться, — d <= n / d вместо d * d <= n:
for (long long d = 2; d <= n / d; ++d) {
if (n % d == 0) {
cout << "NO\n";
return 0;
}
}
Claude 5.5 Sonnet в задаче о максимуме не стала подбирать «начальное значение поменьше». Первое прочитанное число само становится максимумом, поэтому программа верно работает и с одними отрицательными числами:
long long x, mx;
if (!(std::cin >> x)) {
std::cout << "Нет данных\n";
return 0;
}
mx = x;
while (std::cin >> x) {
if (x > mx) mx = x;
}
Чего промпт не сказал, модели придумали сами
Мы запустили решения ещё на нескольких входах, о которых короткий промпт молчал. Засчитывать или не засчитывать тут нечего: правильного ответа условие не задаёт. Зато хорошо видно, как по-разному модели заполняют пробелы.
| Ситуация | GPT-6 Luna | Claude 5.5 Sonnet | GPT-6.1 Sol |
|---|---|---|---|
| Максимум, а чисел нет | ничего не выводит | «Нет данных» | ничего не выводит |
| Среднее при N = 0 | nan | «N must be positive» | ничего не выводит |
Три модели, три разных поведения. Какое из них верное, зависит от задачи, а её знаете только Вы.
Что из этого следует
Слабое место — условие, а не код
На учебных задачах с полным условием модели не ошиблись ни разу. Все расхождения появились там, где промпт оставил место для догадки: в каком порядке идут данные, кто читает вывод, что делать с пустым вводом. Модель не переспрашивает — она выбирает самый вероятный вариант и идёт дальше.
Для того, кто учится, это меняет вопрос. Не «можно ли доверять коду нейросети», а «достаточно ли точно я описал задачу».
Что дописать в промпт
- Ограничения. «N до 200 000, числа до 10^9» — от этого зависят и тип данных, и алгоритм.
- Формат ввода и вывода. Порядок чисел, что выводить и в каком виде. Лучше всего — пример входных и выходных данных.
- Крайние случаи. Что делать, если чисел нет, если N равно нулю, если ответ не существует.
- Кто читает вывод. Проверяющая система или человек: от этого зависит, нужны ли приглашения «Введите число».
Подробнее — в статье «Как написать хороший промпт: четыре части и примеры».
Проверять всё равно нужно
Даже верное решение стоит прогнать на собственных тестах. Минимальный набор:
- Пример из условия.
- Самый маленький вход: одно число, пустая строка, ноль.
- Самый большой вход, разрешённый ограничениями.
- Отрицательные числа, если они допустимы.
- Случай, когда ответа нет.
Если Вы не можете придумать такие тесты, значит, задача ещё не понята — и готовое решение Вас не выручит на контрольной.
Когда учитесь — не просите решение
Модели решили всё, и в этом главная опасность для ученика. Решённая за Вас задача ничему не учит. Просите подсказку, проверку своего кода или контрпример к нему — об этом статья «Как учиться с нейросетью и не разучиться думать».
Ограничения эксперимента
- Десять задач и один запуск на каждую пару — это мало. Ответы моделей случайны: при повторе результат может отличаться.
- Задачи простые и похожи на тысячи задач из учебников. На олимпиадных задачах, больших программах и редких библиотеках картина будет другой.
- Мы проверяли только правильность на тестах, но не стиль кода и не качество объяснений.
- Сравнивать модели между собой по этим данным нельзя: разница в одну задачу из десяти при одном запуске ничего не значит.
Коротко
- 60 решений от трёх моделей, 53 теста с ловушками.
- С полным условием все 30 решений прошли все тесты.
- С коротким промптом не прошли 4 из 30 — и все из-за того, что формат ввода или вывода пришлось угадывать.
- В случаях, которые условие не описывало, модели вели себя по-разному.
- Чем точнее условие, тем надёжнее код. А проверять его тестами нужно в любом случае.
Источники
- Integer overflow и неопределённое поведение — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/language/ub (дата обращения: 10.10.2026).
- std::lower_bound — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/algorithm/lower_bound (дата обращения: 10.10.2026).
- Arithmetic operators: остаток от деления — cppreference.com [Электронный ресурс]. — URL: https://en.cppreference.com/w/cpp/language/operator_arithmetic (дата обращения: 10.10.2026).



