From 3201d65f509987fd6ffb654bfa7cc92f132ab637 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Fri, 26 Jun 2026 13:38:59 +0300 Subject: [PATCH] =?UTF-8?q?feat(trainer):=20V4.1=20=D0=B3=D1=80=D1=83?= =?UTF-8?q?=D0=BF=D0=BF=D0=B0=204=20=E2=80=94=2020=20=D0=B3=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D1=80=D0=B0=D1=82=D0=BE=D1=80=D0=BE=D0=B2=20(=D0=BA?= =?UTF-8?q?=D0=B2=D0=B0=D0=B4=D1=80=D0=B0=D1=82=D0=BD=D1=8B=D0=B5=20+=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B5=D1=81=D1=81=D0=B8=D0=B8)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Четвёртая волна плана v4. «Корень-вперёд»: roots проверяет каждый корень, simplify — эквивалентность, compute — целое. Квадратные (quadratic): quad-incomplete-bx (ax²+bx=0), quad-incomplete-c (ax²=c), quad-disc-clean (через дискриминант, чистый D), quad-trinomial-factor (разложить трёхчлен), quad-find-b (найти b по корню), quad-count-roots (сколько корней по знаку D), quad-vertex-x (абсцисса вершины), quad-complete-square (полный квадрат); формулировки по Виета: quad-roots-sum, quad-roots-prod, quad-build-eq (составить уравнение по корням), quad-double-root (кратный корень, D=0). Прогрессии (progressions): prog-arith-sum (сумма арифм.), prog-arith-find-d (найти разность), prog-arith-find-n (номер члена), prog-arith-mean (среднее арифм.), prog-geom-find-q (знаменатель), prog-geom-mean (геом. среднее √(ac)), prog-geom-sum (сумма геом.), prog-arith-word (ряды кресел). Итого 136 генераторов. Смоук 36748 проверок (roots: переменное число корней, вкл. кратный; simplify: приём канон.+отказ off-by-one; compute: целое; все шаги→LaTeX); геометрия не задета (6968/0). Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/js/trainer/generators.js | 303 ++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) diff --git a/frontend/js/trainer/generators.js b/frontend/js/trainer/generators.js index 1e6b90a..8590b9a 100644 --- a/frontend/js/trainer/generators.js +++ b/frontend/js/trainer/generators.js @@ -1900,6 +1900,303 @@ { note: 'При умножении степеней с одинаковым основанием показатели складываются.', tex: 'x = {a} + {b}' }, { note: 'Считаем.', tex: 'x = {ans}' } ] + }, + + /* ═══════════════════════════════════════════════════════════════════════ + V4.1 — Группа 4: квадратные уравнения и прогрессии. «Корень-вперёд» → + целые корни/ответы; roots проверяет каждый корень, simplify — эквивалентность. + ═══════════════════════════════════════════════════════════════════════ */ + + /* ── Квадратные ── */ + + /* ax² + bx = 0 — вынесение x */ + { + id: 'quad-incomplete-bx', topic: 'quadratic', order: 3, subject: 'algebra', grade: 8, kind: 'roots', + title: 'ax² + bx = 0', + pick: { a: [2, 5], r: [-6, 6] }, constraint: 'r != 0', + derive: { b: '-a*r' }, + lhs: '{a}*x^2 + {b}*x', rhs: '0', display: '{a}x² + {b}x = 0', + answerVar: 'x', answers: ['0', 'r'], integerAnswer: true, + solution: [ + { note: 'Выносим общий множитель x за скобку.', tex: 'x*({a}*x + {b}) = 0' }, + { note: 'Произведение равно нулю — первый корень:', tex: 'x = 0' }, + { note: 'Из второго множителя {a}x + {b} = 0:', tex: 'x = {r}' } + ] + }, + + /* ax² = c — извлечение корня */ + { + id: 'quad-incomplete-c', topic: 'quadratic', order: 4, subject: 'algebra', grade: 8, kind: 'roots', + title: 'ax² = c', + pick: { a: [1, 4], r: [2, 9] }, + derive: { c: 'a*r*r', r2: 'r*r' }, + lhs: '{a}*x^2 - {c}', rhs: '0', display: '{a}x² − {c} = 0', + answerVar: 'x', answers: ['r', '-r'], integerAnswer: true, + solution: [ + { note: 'Переносим {c} вправо и делим на {a}.', tex: 'x^2 = {r2}' }, + { note: 'Извлекаем квадратный корень — первый корень:', tex: 'x = {r}' }, + { note: 'Второй корень — со знаком минус:', tex: 'x = -{r}' } + ] + }, + + /* ax² + bx + c = 0 — через дискриминант (чистый D) */ + { + id: 'quad-disc-clean', topic: 'quadratic', order: 5, subject: 'algebra', grade: 8, kind: 'roots', + title: 'Через дискриминант', + pick: { a: [2, 3], r1: [-4, 4], r2: [-4, 4] }, constraint: 'r1 != r2', + derive: { b: '-a*(r1 + r2)', c: 'a*r1*r2', disc: 'a*a*(r1 - r2)*(r1 - r2)', sqd: 'a*abs(r1 - r2)' }, + lhs: '{a}*x^2 + {b}*x + {c}', rhs: '0', display: '{a}x² + {b}x + {c} = 0', + answerVar: 'x', answers: ['r1', 'r2'], integerAnswer: true, + solution: [ + { note: 'Дискриминант D = b² − 4ac.', tex: 'D = {b}^2 - 4*{a}*{c}' }, + { note: 'Считаем дискриминант.', tex: 'D = {disc}' }, + { note: 'Корни x = (−b ± √D)/(2a), где √D = {sqd}. Первый корень:', tex: 'x = {r1}' }, + { note: 'Второй корень:', tex: 'x = {r2}' } + ] + }, + + /* разложить трёхчлен на множители */ + { + id: 'quad-trinomial-factor', topic: 'quadratic', order: 6, subject: 'algebra', grade: 8, kind: 'simplify', + title: 'Разложить трёхчлен', + pick: { r1: [-6, 6], r2: [-6, 6] }, constraint: 'r1 != r2', + derive: { b: '-(r1 + r2)', c: 'r1*r2' }, + srcExpr: 'x^2 + {b}*x + {c}', answerExpr: '(x - {r1})*(x - {r2})', answerVars: ['x'], + display: 'Разложите на множители: x² + {b}x + {c}', + solution: [ + { note: 'По теореме Виета ищем два числа с суммой −({b}) и произведением {c}: это {r1} и {r2}.', tex: '' }, + { note: 'Разложение на множители:', tex: '(x - {r1})*(x - {r2})' } + ] + }, + + /* найти b по одному корню */ + { + id: 'quad-find-b', topic: 'quadratic', order: 7, subject: 'algebra', grade: 8, kind: 'compute', + title: 'Найти b по корню', + pick: { r: [-6, 6], k: [-6, 6] }, constraint: 'r != 0 && k != 0 && k != r', + derive: { c: 'r*k', b: '-(r + k)' }, + lhs: 'x', rhs: '{b}', display: 'Один из корней уравнения x² + bx + {c} = 0 равен {r}. Найдите b.', + answerVar: 'x', answer: 'b', integerAnswer: true, + solution: [ + { note: 'Подставляем корень x = {r} в уравнение.', tex: '{r}^2 + b*{r} + {c} = 0' }, + { note: 'Выражаем b.', tex: 'b = -({r}^2 + {c}) / {r}' }, + { note: 'Считаем.', tex: 'b = {ans}' } + ] + }, + + /* сколько корней (знак дискриминанта) */ + { + id: 'quad-count-roots', topic: 'quadratic', order: 8, subject: 'algebra', grade: 8, kind: 'compute', + title: 'Сколько корней', + pick: { a: [1, 3], b: [-8, 8], c: [-6, 9] }, + derive: { disc: 'b*b - 4*a*c', nroots: 'disc > 0 ? 2 : (disc == 0 ? 1 : 0)' }, + lhs: 'x', rhs: '{nroots}', display: 'Сколько действительных корней у уравнения {a}x² + {b}x + {c} = 0? (введите 0, 1 или 2)', + answerVar: 'x', answer: 'nroots', integerAnswer: true, + solution: [ + { note: 'Считаем дискриминант D = b² − 4ac.', tex: 'D = {b}^2 - 4*{a}*{c}' }, + { note: 'D = {disc}. Если D > 0 — два корня, D = 0 — один, D < 0 — корней нет.', tex: 'D = {disc}' }, + { note: 'Ответ.', tex: 'x = {ans}' } + ] + }, + + /* абсцисса вершины параболы */ + { + id: 'quad-vertex-x', topic: 'quadratic', order: 9, subject: 'algebra', grade: 8, kind: 'compute', + title: 'Вершина параболы', + pick: { a: [1, 4], xv: [-6, 6], c: [-5, 9] }, constraint: 'xv != 0', + derive: { b: '-2*a*xv' }, + lhs: 'x', rhs: '{xv}', display: 'Найдите абсциссу вершины параболы y = {a}x² + {b}x + {c} (ось симметрии x₀).', + answerVar: 'x', answer: 'xv', integerAnswer: true, + solution: [ + { note: 'Абсцисса вершины: x₀ = −b/(2a).', tex: 'x = -{b} / (2*{a})' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* выделить полный квадрат */ + { + id: 'quad-complete-square', topic: 'quadratic', order: 10, subject: 'algebra', grade: 9, kind: 'simplify', + title: 'Выделить полный квадрат', + pick: { p: [-6, 6], k: [-5, 9] }, constraint: 'p != 0', + derive: { b: '2*p', c: 'p*p + k' }, + srcExpr: 'x^2 + {b}*x + {c}', answerExpr: '(x + {p})^2 + {k}', answerVars: ['x'], + display: 'Выделите полный квадрат: x² + {b}x + {c}', + solution: [ + { note: 'Берём половину коэффициента при x: {b}/2 = {p}. Прибавляем и вычитаем {p}².', tex: 'x^2 + {b}*x + {p}^2 - {p}^2 + {c}' }, + { note: 'Сворачиваем полный квадрат.', tex: '(x + {p})^2 + {k}' } + ] + }, + + /* сумма корней (Виета) */ + { + id: 'quad-roots-sum', topic: 'quadratic', order: 11, subject: 'algebra', grade: 8, kind: 'compute', + title: 'Сумма корней (Виета)', + pick: { r1: [-7, 7], r2: [-7, 7] }, constraint: 'r1 != r2', + derive: { b: '-(r1 + r2)', c: 'r1*r2', sum: 'r1 + r2' }, + lhs: 'x', rhs: '{r1} + {r2}', display: 'Найдите сумму корней уравнения x² + {b}x + {c} = 0.', + answerVar: 'x', answer: 'sum', integerAnswer: true, + solution: [ + { note: 'По теореме Виета сумма корней приведённого уравнения равна −b.', tex: 'x = -({b})' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* произведение корней (Виета) */ + { + id: 'quad-roots-prod', topic: 'quadratic', order: 12, subject: 'algebra', grade: 8, kind: 'compute', + title: 'Произведение корней (Виета)', + pick: { r1: [-7, 7], r2: [-7, 7] }, constraint: 'r1 != r2 && r1 != 0 && r2 != 0', + derive: { b: '-(r1 + r2)', c: 'r1*r2', prod: 'r1*r2' }, + lhs: 'x', rhs: '{r1}*{r2}', display: 'Найдите произведение корней уравнения x² + {b}x + {c} = 0.', + answerVar: 'x', answer: 'prod', integerAnswer: true, + solution: [ + { note: 'По теореме Виета произведение корней приведённого уравнения равно свободному члену c.', tex: 'x = {c}' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* составить уравнение по корням */ + { + id: 'quad-build-eq', topic: 'quadratic', order: 13, subject: 'algebra', grade: 8, kind: 'simplify', + title: 'Составить уравнение по корням', + pick: { r1: [-6, 6], r2: [-6, 6] }, constraint: 'r1 != r2', + derive: { b: '-(r1 + r2)', c: 'r1*r2' }, + srcExpr: '(x - {r1})*(x - {r2})', answerExpr: 'x^2 + {b}*x + {c}', answerVars: ['x'], + display: 'Составьте приведённое квадратное уравнение (левую часть) с корнями {r1} и {r2}.', + solution: [ + { note: 'По Виета: сумма корней = −b, произведение = c. Значит b = −({r1} + {r2}), c = {r1}·{r2}.', tex: '' }, + { note: 'Левая часть уравнения:', tex: 'x^2 + {b}*x + {c}' } + ] + }, + + /* двойной (кратный) корень */ + { + id: 'quad-double-root', topic: 'quadratic', order: 14, subject: 'algebra', grade: 8, kind: 'roots', + title: 'Кратный корень (D = 0)', + pick: { p: [-7, 7] }, constraint: 'p != 0', + derive: { b: '2*p', c: 'p*p' }, + lhs: 'x^2 + {b}*x + {c}', rhs: '0', display: 'x² + {b}x + {c} = 0', + answerVar: 'x', answers: ['-p'], integerAnswer: true, + solution: [ + { note: 'Это полный квадрат: x² + {b}x + {c} = (x + {p})².', tex: '(x + {p})^2 = 0' }, + { note: 'Дискриминант равен нулю — единственный корень:', tex: 'x = -{p}' } + ] + }, + + /* ── Прогрессии ── */ + + /* сумма n членов арифметической прогрессии */ + { + id: 'prog-arith-sum', topic: 'progressions', order: 3, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Сумма арифм. прогрессии', + pick: { a: [-8, 12], d: [-6, 6], n: [4, 12] }, require: 'd != 0', + derive: { an: 'a + (n - 1)*d', sum: 'n*(a + an)/2' }, + lhs: 'x', rhs: '{n}*({a} + {an})/2', display: 'Арифметическая прогрессия: a₁ = {a}, d = {d}. Найдите сумму первых {n} членов.', + answerVar: 'x', answer: 'sum', integerAnswer: true, + solution: [ + { note: 'Сначала {n}-й член: aₙ = a₁ + (n − 1)d = {an}.', tex: '{a} + ({n} - 1)*{d} = {an}' }, + { note: 'Сумма Sₙ = n(a₁ + aₙ)/2.', tex: 'x = {n} * ({a} + {an}) / 2' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* найти разность d по двум членам */ + { + id: 'prog-arith-find-d', topic: 'progressions', order: 4, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Найти разность d', + pick: { a: [-6, 10], d: [-5, 5], n: [4, 10] }, require: 'd != 0', + derive: { an: 'a + (n - 1)*d' }, + lhs: 'x', rhs: '({an} - {a})/({n} - 1)', display: 'В арифметической прогрессии a₁ = {a}, а член с номером {n} равен {an}. Найдите разность d.', + answerVar: 'x', answer: 'd', integerAnswer: true, + solution: [ + { note: 'Из формулы aₙ = a₁ + (n − 1)d выражаем d.', tex: 'd = ({an} - {a}) / ({n} - 1)' }, + { note: 'Считаем.', tex: 'd = {ans}' } + ] + }, + + /* найти номер члена n */ + { + id: 'prog-arith-find-n', topic: 'progressions', order: 5, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Номер члена прогрессии', + pick: { a: [-6, 10], d: [-5, 5], n: [4, 12] }, require: 'd != 0', + derive: { an: 'a + (n - 1)*d' }, + lhs: 'x', rhs: '({an} - {a})/{d} + 1', display: 'В арифметической прогрессии a₁ = {a}, d = {d}. Каким по счёту является член, равный {an}?', + answerVar: 'x', answer: 'n', integerAnswer: true, + solution: [ + { note: 'Из aₙ = a₁ + (n − 1)d выражаем номер n.', tex: 'n = ({an} - {a}) / {d} + 1' }, + { note: 'Считаем.', tex: 'n = {ans}' } + ] + }, + + /* среднее арифметическое (вставить член) */ + { + id: 'prog-arith-mean', topic: 'progressions', order: 6, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Среднее арифметическое', + pick: { m: [-9, 9], d: [-7, 7] }, require: 'd != 0', + derive: { a: 'm - d', c: 'm + d' }, + lhs: 'x', rhs: '({a} + {c})/2', display: 'Числа {a}, x, {c} образуют арифметическую прогрессию. Найдите x.', + answerVar: 'x', answer: 'm', integerAnswer: true, + solution: [ + { note: 'Средний член равен среднему арифметическому соседних: x = (a + c)/2.', tex: 'x = ({a} + {c}) / 2' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* найти знаменатель q */ + { + id: 'prog-geom-find-q', topic: 'progressions', order: 7, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Найти знаменатель q', + pick: { b: [1, 5], q: [2, 4] }, + derive: { b2: 'b*q' }, + lhs: 'x', rhs: '{b2}/{b}', display: 'Геометрическая прогрессия: b₁ = {b}, b₂ = {b2}. Найдите знаменатель q.', + answerVar: 'x', answer: 'q', integerAnswer: true, + solution: [ + { note: 'Знаменатель — отношение соседних членов: q = b₂/b₁.', tex: 'q = {b2} / {b}' }, + { note: 'Считаем.', tex: 'q = {ans}' } + ] + }, + + /* геометрическое среднее (вставить член) */ + { + id: 'prog-geom-mean', topic: 'progressions', order: 8, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Геометрическое среднее', + pick: { g: [2, 10], q: [2, 3] }, require: 'mod(g, q) == 0', + derive: { a: 'g/q', c: 'g*q' }, + lhs: 'x', rhs: 'sqrt({a}*{c})', display: 'Числа {a}, x, {c} образуют геометрическую прогрессию (все положительны). Найдите x.', + answerVar: 'x', answer: 'g', integerAnswer: true, + solution: [ + { note: 'Средний член геометрической прогрессии: x = √(a · c).', tex: 'x = sqrt({a} * {c})' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* сумма n членов геометрической прогрессии */ + { + id: 'prog-geom-sum', topic: 'progressions', order: 9, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Сумма геом. прогрессии', + pick: { b: [1, 4], q: [2, 3], n: [2, 5] }, + derive: { qn: 'q^n', sum: 'b*(q^n - 1)/(q - 1)' }, + lhs: 'x', rhs: '{b}*({q}^{n} - 1)/({q} - 1)', display: 'Геометрическая прогрессия: b₁ = {b}, q = {q}. Найдите сумму первых {n} членов.', + answerVar: 'x', answer: 'sum', integerAnswer: true, + solution: [ + { note: 'Сумма Sₙ = b₁(qⁿ − 1)/(q − 1).', tex: 'x = {b} * ({q}^{n} - 1) / ({q} - 1)' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] + }, + + /* текстовая задача (ряды кресел) */ + { + id: 'prog-arith-word', topic: 'progressions', order: 10, subject: 'algebra', grade: 9, kind: 'compute', + title: 'Задача (ряды кресел)', + pick: { a: [10, 20], d: [2, 5], n: [5, 12] }, + derive: { an: 'a + (n - 1)*d', sum: 'n*(a + an)/2' }, + lhs: 'x', rhs: '{n}*({a} + {an})/2', display: 'В первом ряду зала {a} кресел, в каждом следующем на {d} больше. Сколько всего кресел в {n} рядах?', + answerVar: 'x', answer: 'sum', integerAnswer: true, + solution: [ + { note: 'Кресла по рядам — арифметическая прогрессия. В последнем ряду: {a} + ({n} − 1)·{d} = {an}.', tex: '{a} + ({n} - 1)*{d} = {an}' }, + { note: 'Всего кресел — сумма Sₙ = n(a₁ + aₙ)/2.', tex: 'x = {n} * ({a} + {an}) / 2' }, + { note: 'Считаем.', tex: 'x = {ans}' } + ] } ]; @@ -1957,6 +2254,12 @@ 'diff-sq-factor': 3, 'sq-trinom-factor': 3, 'sq-sum-coef': 3, 'cube-sum': 3, 'sum-cubes-factor': 3, 'fmt-blank-square': 2, 'fmt-fix-square': 3, 'pow-div': 2, 'pow-product-base': 2, 'pow-frac-combine': 3, 'pow-numeric-laws': 2, 'pow-standard-form': 2, 'pow-which-law': 2, + // V4.1 — Квадратные/Прогрессии + 'quad-incomplete-bx': 2, 'quad-incomplete-c': 2, 'quad-disc-clean': 3, 'quad-trinomial-factor': 2, + 'quad-find-b': 3, 'quad-count-roots': 2, 'quad-vertex-x': 2, 'quad-complete-square': 3, + 'quad-roots-sum': 2, 'quad-roots-prod': 2, 'quad-build-eq': 3, 'quad-double-root': 2, + 'prog-arith-sum': 2, 'prog-arith-find-d': 2, 'prog-arith-find-n': 3, 'prog-arith-mean': 2, + 'prog-geom-find-q': 2, 'prog-geom-mean': 3, 'prog-geom-sum': 3, 'prog-arith-word': 2, // НОД/НОК / Дроби / Десятичные / Отрицательные 'gcd-pair': 1, 'lcm-pair': 2, 'frac-of-number': 1, 'frac-add-same': 2,