Files
Learn_System/frontend/js/trainer/generators.js
T
Maxim Dolgolyov 169501f12a feat(trainer): контент 5-6 кл — десятичные дроби + отрицательные числа
- НОВАЯ тема Десятичные (5 кл): сложение/вычитание/умножение десятичных. Строятся через десятые/сотые (целые ÷10, ÷100) → ответ печатается чисто, без float-мусора (0.8, 0.07, 0.16)
- НОВАЯ тема Отрицательные (6 кл): сумма/разность/произведение с отрицательными. Словесные формулировки («Найдите сумму чисел -8 и 9», «Из числа 6 вычтите -12») — без двусмысленных операторов; constraint гарантирует хотя бы одно отрицательное
- всё kind compute (движок не трогал); LEVELS проставлены
- 58 генераторов, 19 тем; смоук движка 1114/1114, страница 40/40; эмодзи 0

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 17:17:22 +03:00

984 lines
57 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/* ════════════════════════════════════════════════════════════════════════
Генераторы задач тренажёра — ДАННЫЕ, не код. Таксономия: тема → навык.
Приём «корень-вперёд»: выбираем целый корень/множители и коэффициенты, затем
ВЫВОДИМ остальное так, чтобы ответ был целым, а задача — решаемой. Поэтому
самопроверка движка (verifyRoot) всегда проходит. Шаг решения —
{ note(подробный текст), tex(одно равенство) }; tex рендерится в KaTeX
(exprToLatex). Последний шаг «Проверка» подставляет корень — это и педагогика,
и наглядная демонстрация того, как движок проверяет ответ.
Виды задач:
• solve (деф.) — уравнение lhs = rhs, ученик находит x. Показывается уравнение.
• compute (kind:'compute') — вычислительная задача (проценты): на сцене —
текстовый prompt из display, а lhs:'x' / rhs:<значение> служат ТОЛЬКО для
проверки ответа подстановкой (latex уравнения не показывается).
Темы (7 класс, алгебра): Уравнения → Пропорции → Проценты. Дальше (Уровень 1):
текстовые задачи через LLM с той же подстановочной верификацией.
════════════════════════════════════════════════════════════════════════ */
(function (global) {
// Классы по программе наших учебников (Алгебра/Геометрия 7–9).
var TOPICS = [
{ key: 'linear-eq', label: 'Уравнения', subject: 'algebra', grade: 7, order: 1 },
{ key: 'proportions', label: 'Пропорции', subject: 'algebra', grade: 6, order: 2 },
{ key: 'percents', label: 'Проценты', subject: 'algebra', grade: 6, order: 3 },
{ key: 'simplify', label: 'Упрощение', subject: 'algebra', grade: 7, order: 4 },
{ key: 'powers', label: 'Степени', subject: 'algebra', grade: 7, order: 5 },
{ key: 'formulas', label: 'Формулы', subject: 'algebra', grade: 7, order: 6 },
{ key: 'inequalities', label: 'Неравенства', subject: 'algebra', grade: 7, order: 7 },
{ key: 'systems', label: 'Системы', subject: 'algebra', grade: 7, order: 8 },
{ key: 'quadratic', label: 'Квадратные', subject: 'algebra', grade: 8, order: 9 },
{ key: 'progressions', label: 'Прогрессии', subject: 'algebra', grade: 9, order: 10 },
{ key: 'fractions', label: 'Дроби', subject: 'algebra', grade: 5, order: 1.5 },
{ key: 'decimals', label: 'Десятичные', subject: 'algebra', grade: 5, order: 1.6 },
{ key: 'negatives', label: 'Отрицательные', subject: 'algebra', grade: 6, order: 1.7 },
{ key: 'applied', label: 'Задачи', subject: 'algebra', grade: 7, order: 11 },
{ key: 'g-angles', label: 'Углы', subject: 'geometry', grade: 7, order: 12 },
{ key: 'g-pyth', label: 'Пифагор', subject: 'geometry', grade: 8, order: 13 },
{ key: 'g-area', label: 'Площади', subject: 'geometry', grade: 8, order: 14 },
{ key: 'g-poly', label: 'Многоугольники', subject: 'geometry', grade: 8, order: 15 },
{ key: 'g-sim', label: 'Подобие', subject: 'geometry', grade: 8, order: 16 }
];
var GENERATORS = [
/* ═══ Тема: Уравнения ═══ */
/* ax + b = c */
{
id: 'lin-basic', topic: 'linear-eq', order: 1, subject: 'algebra', grade: 7,
title: 'ax + b = c',
pick: { a: [2, 9], b: [1, 20], root: [-9, 9] },
require: 'root != 0',
derive: { c: 'a*root + b', cmb: 'a*root' },
lhs: '{a}*x + {b}', rhs: '{c}', display: '{a}x + {b} = {c}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Перед нами линейное уравнение. Наша цель — оставить x одного в левой части. Сначала уберём свободное число {b}: перенесём его вправо, поменяв знак.', tex: '{a}x = {c} - {b}' },
{ note: 'Выполняем вычитание в правой части.', tex: '{a}x = {cmb}' },
{ note: 'Осталось избавиться от множителя при x — делим обе части уравнения на {a}.', tex: 'x = {cmb} / {a}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставим найденное значение в исходное уравнение — левая часть должна совпасть с правой.', tex: '{a}*({ans}) + {b} = {c}' }
]
},
/* a(x + b) = c */
{
id: 'lin-paren', topic: 'linear-eq', order: 2, subject: 'algebra', grade: 7,
title: 'a(x + b) = c',
pick: { a: [2, 8], b: [1, 12], root: [-9, 9] },
require: 'root != 0',
derive: { c: 'a*(root + b)', ca: 'root + b' },
lhs: '{a}*(x + {b})', rhs: '{c}', display: '{a}(x + {b}) = {c}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Слева число {a} умножается на скобку. Самый короткий путь — разделить обе части уравнения на {a}, чтобы убрать этот множитель.', tex: 'x + {b} = {ca}' },
{ note: 'Справа получилось целое число. Теперь переносим {b} вправо со сменой знака.', tex: 'x = {ca} - {b}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставляем корень в скобку исходного уравнения.', tex: '{a}*({ans} + {b}) = {c}' }
]
},
/* ax + b = cx + d */
{
id: 'lin-both-sides', topic: 'linear-eq', order: 3, subject: 'algebra', grade: 7,
title: 'ax + b = cx + d',
pick: { a: [3, 9], c: [1, 8], b: [1, 20], root: [-9, 9] },
constraint: 'c < a', require: 'root != 0',
derive: { d: '(a - c)*root + b', amc: 'a - c', dmb: '(a - c)*root' },
lhs: '{a}*x + {b}', rhs: '{c}*x + {d}', display: '{a}x + {b} = {c}x + {d}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Здесь x есть в обеих частях. Соберём все слагаемые с x слева, а числа — справа. Переносимые слагаемые меняют знак.', tex: '({a} - {c})x = {d} - {b}' },
{ note: 'Приводим подобные: вычитаем коэффициенты при x и отдельно числа.', tex: '{amc}x = {dmb}' },
{ note: 'Делим обе части на коэффициент при x, то есть на {amc}.', tex: 'x = {dmb} / {amc}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставим корень — обе части дадут одно и то же число.', tex: '{a}*({ans}) + {b} = {c}*({ans}) + {d}' }
]
},
/* a(x + b) = c(x + d) */
{
id: 'lin-paren-both', topic: 'linear-eq', order: 4, subject: 'algebra', grade: 7,
title: 'a(x+b) = c(x+d)',
pick: { a: [2, 6], c: [2, 6], b: [1, 10], root: [-6, 6] },
constraint: 'a != c',
derive: { V: 'a*(root + b)', d: 'V/c - root', ab: 'a*b', cd: 'c*(V/c - root)', amc: 'a - c', diff: 'c*(V/c - root) - a*b' },
require: 'mod(V, c) == 0 && root != 0',
lhs: '{a}*(x + {b})', rhs: '{c}*(x + {d})', display: '{a}(x + {b}) = {c}(x + {d})',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Скобки с двух сторон. Раскрываем их: умножаем множитель перед скобкой на каждое слагаемое внутри.', tex: '{a}x + {ab} = {c}x + {cd}' },
{ note: 'Переносим слагаемые с x влево, числа — вправо, и приводим подобные.', tex: '{amc}x = {diff}' },
{ note: 'Делим обе части на {amc}.', tex: 'x = {diff} / {amc}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставляем корень в обе скобки.', tex: '{a}*({ans} + {b}) = {c}*({ans} + {d})' }
]
},
/* x/a + b = c */
{
id: 'lin-frac-denom', topic: 'linear-eq', order: 5, subject: 'algebra', grade: 7,
title: 'x/a + b = c',
pick: { a: [2, 6], k: [-6, 6], b: [1, 12] },
require: 'k != 0',
derive: { root: 'a*k', c: 'k + b', cmb: 'k' },
lhs: 'x/{a} + {b}', rhs: '{c}', display: 'x/{a} + {b} = {c}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Слева — дробь x/{a} и число {b}. Сначала уберём свободное число: вычтем {b} из обеих частей.', tex: 'x/{a} = {cmb}' },
{ note: 'Чтобы избавиться от знаменателя {a}, умножаем обе части уравнения на {a}.', tex: 'x = {cmb} * {a}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставляем корень в исходное уравнение.', tex: '{ans}/{a} + {b} = {c}' }
]
},
/* (a·x)/b = c */
{
id: 'lin-coef-frac', topic: 'linear-eq', order: 6, subject: 'algebra', grade: 7,
title: 'ax/b = c',
pick: { a: [2, 5], b: [2, 5], m: [-5, 5] },
require: 'm != 0',
derive: { root: 'b*m', c: 'a*m', cb: 'a*m*b' },
lhs: '{a}*x/{b}', rhs: '{c}', display: '{a}x/{b} = {c}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Слева дробь, в числителе — {a}x. Умножаем обе части уравнения на знаменатель {b}, чтобы избавиться от дроби.', tex: '{a}x = {cb}' },
{ note: 'Теперь делим обе части на коэффициент {a}.', tex: 'x = {cb} / {a}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставляем корень в исходную дробь.', tex: '{a}*({ans})/{b} = {c}' }
]
},
/* (ax + b)/c = d */
{
id: 'lin-frac-eq', topic: 'linear-eq', order: 7, subject: 'algebra', grade: 7,
title: '(ax + b)/c = d',
pick: { a: [2, 6], b: [1, 12], c: [2, 6], root: [-6, 6] },
derive: { prod: 'a*root + b', d: '(a*root + b)/c', cd: 'a*root + b', cdmb: 'a*root' },
require: 'mod(a*root + b, c) == 0 && root != 0',
lhs: '({a}*x + {b})/{c}', rhs: '{d}', display: '({a}x + {b})/{c} = {d}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Вся левая часть делится на {c}. Умножаем обе части уравнения на {c}, чтобы убрать знаменатель.', tex: '{a}x + {b} = {cd}' },
{ note: 'Переносим число {b} в правую часть со сменой знака.', tex: '{a}x = {cdmb}' },
{ note: 'Делим обе части на {a}.', tex: 'x = {cdmb} / {a}' },
{ note: 'Получаем корень уравнения.', tex: 'x = {ans}' },
{ note: 'Проверка: подставляем корень в исходную дробь.', tex: '({a}*({ans}) + {b})/{c} = {d}' }
]
},
/* ═══ Тема: Пропорции ═══ */
/* a/b = c/x */
{
id: 'prop-x-right', topic: 'proportions', order: 1, subject: 'algebra', grade: 7,
title: 'a/b = c/x',
pick: { a: [2, 9], b: [2, 9], t: [2, 9] },
derive: { c: 'a*t', root: 'b*t', bc: 'b*a*t' },
lhs: '{a}/{b}', rhs: '{c}/x', display: '{a}/{b} = {c}/x',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Это пропорция — равенство двух отношений. По основному свойству пропорции произведение крайних членов равно произведению средних (умножаем «крест-накрест»).', tex: '{a}*x = {b} * {c}' },
{ note: 'Считаем произведение в правой части.', tex: '{a}x = {bc}' },
{ note: 'Делим обе части на {a}, чтобы найти x.', tex: 'x = {bc} / {a}' },
{ note: 'Получаем корень.', tex: 'x = {ans}' },
{ note: 'Проверка: при найденном x обе дроби равны.', tex: '{a}/{b} = {c}/{ans}' }
]
},
/* x/a = b/c */
{
id: 'prop-x-left', topic: 'proportions', order: 2, subject: 'algebra', grade: 7,
title: 'x/a = b/c',
pick: { a: [2, 9], c: [2, 9], s: [2, 9] },
derive: { b: 'c*s', root: 'a*s', ab: 'a*c*s' },
lhs: 'x/{a}', rhs: '{b}/{c}', display: 'x/{a} = {b}/{c}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Перед нами пропорция. Перемножаем её члены крест-накрест: числитель левой дроби на знаменатель правой и наоборот.', tex: '{c}*x = {a} * {b}' },
{ note: 'Считаем произведение в правой части.', tex: '{c}x = {ab}' },
{ note: 'Делим обе части на {c}.', tex: 'x = {ab} / {c}' },
{ note: 'Получаем корень.', tex: 'x = {ans}' },
{ note: 'Проверка: обе дроби равны.', tex: '{ans}/{a} = {b}/{c}' }
]
},
/* a/x = b/c */
{
id: 'prop-x-denom', topic: 'proportions', order: 3, subject: 'algebra', grade: 7,
title: 'a/x = b/c',
pick: { b: [2, 9], c: [2, 9], s: [2, 9] },
derive: { a: 'b*s', root: 'c*s', ac: 'b*s*c' },
lhs: '{a}/x', rhs: '{b}/{c}', display: '{a}/x = {b}/{c}',
answerVar: 'x', answer: 'root', integerAnswer: true,
solution: [
{ note: 'Пропорция, где неизвестное стоит в знаменателе. Перемножаем крест-накрест.', tex: '{b}*x = {a} * {c}' },
{ note: 'Считаем произведение в правой части.', tex: '{b}x = {ac}' },
{ note: 'Делим обе части на {b}.', tex: 'x = {ac} / {b}' },
{ note: 'Получаем корень.', tex: 'x = {ans}' },
{ note: 'Проверка: обе дроби равны.', tex: '{a}/{ans} = {b}/{c}' }
]
},
/* ═══ Тема: Проценты (вычислительные задачи) ═══ */
/* p% от числа a */
{
id: 'pct-of', topic: 'percents', order: 1, subject: 'algebra', grade: 7, kind: 'compute',
title: 'p% от числа',
pick: { pidx: [2, 10], abase: [1, 15] },
derive: { p: 'pidx*5', a: 'abase*20', val: 'pidx*abase' },
lhs: 'x', rhs: '{p}*{a}/100', display: 'Найдите {p}% от числа {a}',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Процент — это сотая доля числа. Чтобы найти {p}% от {a}, нужно умножить число на {p} и разделить на 100.', tex: 'x = {a}*{p}/100' },
{ note: 'Выполняем умножение и деление — получаем ответ.', tex: 'x = {ans}' }
]
},
/* сколько % составляет a от b */
{
id: 'pct-what', topic: 'percents', order: 2, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Сколько процентов',
pick: { pidx: [2, 10], bbase: [1, 8] },
derive: { p: 'pidx*5', b: 'bbase*20', a: 'pidx*bbase' },
lhs: 'x', rhs: '100*{a}/{b}', display: 'Сколько процентов составляет {a} от {b}?',
answerVar: 'x', answer: 'p', integerAnswer: true,
solution: [
{ note: 'Чтобы узнать, какую часть {a} составляет от {b}, делим {a} на {b}. А чтобы перевести эту часть в проценты — умножаем результат на 100.', tex: 'x = {a}/{b}*100' },
{ note: 'Считаем — ответ получается в процентах.', tex: 'x = {ans}' }
]
},
/* p% числа равны a — найти число */
{
id: 'pct-whole', topic: 'percents', order: 3, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Число по проценту',
pick: { pidx: [2, 10], wbase: [1, 12] },
derive: { p: 'pidx*5', whole: 'wbase*20', a: 'pidx*wbase' },
lhs: 'x', rhs: '100*{a}/{p}', display: '{p}% числа равны {a}. Найдите это число.',
answerVar: 'x', answer: 'whole', integerAnswer: true,
solution: [
{ note: 'Известно, что {p}% некоторого числа равны {a}. Значит само число во столько раз больше: умножаем {a} на 100 и делим на {p}.', tex: 'x = {a}*100/{p}' },
{ note: 'Считаем — получаем искомое число.', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Упрощение выражений (проверка эквивалентностью) ═══ */
/* a·x + b·x → (a+b)x */
{
id: 'simp-like', topic: 'simplify', order: 1, subject: 'algebra', grade: 7, kind: 'simplify',
title: 'Привести подобные',
pick: { a: [2, 9], b: [2, 9] },
derive: { s: 'a + b' },
srcExpr: '{a}*x + {b}*x', answerExpr: '{s}*x', answerVars: ['x'],
display: 'Упростите: {a}x + {b}x',
solution: [
{ note: 'Оба слагаемых содержат x — это подобные слагаемые. Складываем их коэффициенты: {a} + {b} = {s}.', tex: '{a}x + {b}x = {s}x' }
]
},
/* a(x + b) → ax + ab */
{
id: 'simp-expand', topic: 'simplify', order: 2, subject: 'algebra', grade: 7, kind: 'simplify',
title: 'Раскрыть скобки',
pick: { a: [2, 9], b: [1, 9] },
derive: { ab: 'a*b' },
srcExpr: '{a}*(x + {b})', answerExpr: '{a}*x + {ab}', answerVars: ['x'],
display: 'Раскройте скобки: {a}(x + {b})',
solution: [
{ note: 'Умножаем множитель {a} на каждое слагаемое внутри скобки.', tex: '{a}(x + {b}) = {a}x + {ab}' }
]
},
/* ═══ Тема: Квадратные уравнения (несколько корней) ═══ */
/* x² + bx + c = 0 — разложение по Виета (два корня r1, r2) */
{
id: 'quad-factored', topic: 'quadratic', order: 1, subject: 'algebra', grade: 8, kind: 'roots',
title: 'x² + bx + c = 0',
pick: { r1: [-7, 7], r2: [-7, 7] },
constraint: 'r1 != r2',
derive: { b: '-(r1 + r2)', c: 'r1*r2' },
lhs: 'x^2 + {b}*x + {c}', rhs: '0',
answerVar: 'x', answers: ['r1', 'r2'], integerAnswer: true,
solution: [
{ note: 'Квадратное уравнение приравнено к нулю. По теореме Виета ищем два числа: их сумма равна {r1}+{r2}, произведение — {c}. Это и есть корни. Раскладываем на множители:', tex: '(x - {r1})(x - {r2}) = 0' },
{ note: 'Произведение равно нулю, когда обнуляется множитель. Первый корень:', tex: 'x = {r1}' },
{ note: 'Второй корень:', tex: 'x = {r2}' }
]
},
/* x² − a² = 0 — разность квадратов (корни ±a) */
{
id: 'quad-diff', topic: 'quadratic', order: 2, subject: 'algebra', grade: 8, kind: 'roots',
title: 'x² a² = 0',
pick: { a: [2, 9] },
derive: { a2: 'a*a' },
lhs: 'x^2 - {a2}', rhs: '0',
answerVar: 'x', answers: ['a', '-a'], integerAnswer: true,
solution: [
{ note: 'Слева — разность квадратов: x² − {a2} = (x {a})(x + {a}). Раскладываем:', tex: '(x - {a})(x + {a}) = 0' },
{ note: 'Первый корень:', tex: 'x = {a}' },
{ note: 'Второй корень:', tex: 'x = -{a}' }
]
},
/* ═══ Тема: Степени ═══ */
/* вычислить aⁿ */
{
id: 'pow-eval', topic: 'powers', order: 1, subject: 'algebra', grade: 8, kind: 'compute',
title: 'Вычислить степень',
pick: { a: [2, 6], n: [2, 3] },
derive: { val: 'a^n' },
lhs: 'x', rhs: '{a}^{n}', display: 'Вычислите {a} в степени {n}',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Степень — это повторное умножение основания на себя.', tex: 'x = {a}^{n}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* xᵃ · xᵇ = xᵃ⁺ᵇ */
{
id: 'pow-mult', topic: 'powers', order: 2, subject: 'algebra', grade: 8, kind: 'simplify',
title: 'Произведение степеней',
pick: { a: [2, 5], b: [2, 5] },
derive: { s: 'a + b' },
srcExpr: 'x^{a}*x^{b}', answerExpr: 'x^{s}', answerVars: ['x'],
display: 'Упростите: x^{a}·x^{b}',
solution: [
{ note: 'При умножении степеней с одинаковым основанием показатели складываются: {a} + {b} = {s}.', tex: 'x^{a}*x^{b} = x^{s}' }
]
},
/* (xᵃ)ᵇ = xᵃᵇ */
{
id: 'pow-pow', topic: 'powers', order: 3, subject: 'algebra', grade: 8, kind: 'simplify',
title: 'Степень степени',
pick: { a: [2, 4], b: [2, 3] },
derive: { ab: 'a*b' },
srcExpr: '(x^{a})^{b}', answerExpr: 'x^{ab}', answerVars: ['x'],
display: 'Упростите: (x^{a})^{b}',
solution: [
{ note: 'При возведении степени в степень показатели перемножаются: {a}·{b} = {ab}.', tex: '(x^{a})^{b} = x^{ab}' }
]
},
/* ═══ Тема: Формулы сокращённого умножения ═══ */
/* (x + a)² */
{
id: 'sq-sum', topic: 'formulas', order: 1, subject: 'algebra', grade: 8, kind: 'simplify',
title: 'Квадрат суммы',
pick: { a: [1, 9] },
derive: { a2: 'a*a', a2x: '2*a' },
srcExpr: '(x + {a})^2', answerExpr: 'x^2 + {a2x}*x + {a2}', answerVars: ['x'],
display: 'Раскройте: (x + {a})²',
solution: [
{ note: 'Квадрат суммы: (x + {a})² = x² + 2·{a}·x + {a}².', tex: '(x + {a})^2 = x^2 + {a2x}*x + {a2}' }
]
},
/* (x a)² */
{
id: 'sq-diff', topic: 'formulas', order: 2, subject: 'algebra', grade: 8, kind: 'simplify',
title: 'Квадрат разности',
pick: { a: [1, 9] },
derive: { a2: 'a*a', a2x: '2*a' },
srcExpr: '(x - {a})^2', answerExpr: 'x^2 - {a2x}*x + {a2}', answerVars: ['x'],
display: 'Раскройте: (x {a})²',
solution: [
{ note: 'Квадрат разности: (x − {a})² = x² 2·{a}·x + {a}².', tex: '(x - {a})^2 = x^2 - {a2x}*x + {a2}' }
]
},
/* (x a)(x + a) = x² a² */
{
id: 'diff-sq', topic: 'formulas', order: 3, subject: 'algebra', grade: 8, kind: 'simplify',
title: 'Разность квадратов',
pick: { a: [2, 9] },
derive: { a2: 'a*a' },
srcExpr: '(x - {a})*(x + {a})', answerExpr: 'x^2 - {a2}', answerVars: ['x'],
display: 'Раскройте: (x {a})(x + {a})',
solution: [
{ note: 'Произведение разности и суммы даёт разность квадратов: (x − {a})(x + {a}) = x² {a}².', tex: '(x - {a})*(x + {a}) = x^2 - {a2}' }
]
},
/* ═══ Тема: Линейные неравенства ═══ */
/* ax + b < c (a>0, знак сохраняется) */
{
id: 'ineq-lt', topic: 'inequalities', order: 1, subject: 'algebra', grade: 8, kind: 'inequality',
title: 'ax + b < c',
pick: { a: [2, 6], b: [1, 15], root: [-8, 8] },
derive: { c: 'a*root + b', cmb: 'a*root' },
lhs: '{a}*x + {b}', rhs: '{c}', dispOp: '<', relOp: '<', bound: 'root',
answerVar: 'x',
solution: [
{ note: 'Переносим свободный член {b} вправо:', tex: '{a}x < {cmb}' },
{ note: 'Делим обе части на {a} — число положительное, знак неравенства не меняется:', tex: 'x < {root}' }
]
},
/* ax + b ≥ c (a>0) */
{
id: 'ineq-ge', topic: 'inequalities', order: 2, subject: 'algebra', grade: 8, kind: 'inequality',
title: 'ax + b ≥ c',
pick: { a: [2, 6], b: [1, 15], root: [-8, 8] },
derive: { c: 'a*root + b', cmb: 'a*root' },
lhs: '{a}*x + {b}', rhs: '{c}', dispOp: '>=', relOp: '>=', bound: 'root',
answerVar: 'x',
solution: [
{ note: 'Переносим {b} вправо:', tex: '{a}x >= {cmb}' },
{ note: 'Делим на {a} (положительное) — знак сохраняется:', tex: 'x >= {root}' }
]
},
/* ax + b < c (коэффициент отрицательный → знак МЕНЯЕТСЯ) */
{
id: 'ineq-flip', topic: 'inequalities', order: 3, subject: 'algebra', grade: 8, kind: 'inequality',
title: 'ax + b < c (смена знака)',
pick: { a: [2, 6], b: [1, 15], root: [-8, 8] },
derive: { c: 'b - a*root', cmb: '-a*root' },
lhs: '-{a}*x + {b}', rhs: '{c}', dispOp: '<', relOp: '>', bound: 'root',
answerVar: 'x',
solution: [
{ note: 'Переносим {b} вправо:', tex: '-{a}x < {cmb}' },
{ note: 'Делим на отрицательное число (−{a}) — знак неравенства МЕНЯЕТСЯ на противоположный:', tex: 'x > {root}' }
]
},
/* ═══ Тема: Прогрессии (9 класс) ═══ */
/* n-й член арифметической прогрессии */
{
id: 'prog-arith-term', topic: 'progressions', order: 1, subject: 'algebra', grade: 9, kind: 'compute',
title: 'n-й член арифм. прогрессии',
pick: { a: [-10, 20], d: [-8, 8], n: [3, 12] }, require: 'd != 0',
derive: { val: 'a + (n - 1)*d' },
lhs: 'x', rhs: '{a} + ({n} - 1)*{d}', display: 'Арифметическая прогрессия: a₁ = {a}, d = {d}. Найдите {n}-й член.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Формула n-го члена арифметической прогрессии: aₙ = a₁ + (n − 1)·d. Подставляем:', tex: 'x = {a} + ({n} - 1)*{d}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* n-й член геометрической прогрессии */
{
id: 'prog-geom-term', topic: 'progressions', order: 2, subject: 'algebra', grade: 9, kind: 'compute',
title: 'n-й член геом. прогрессии',
pick: { b: [1, 5], q: [2, 3], n: [2, 4] },
derive: { val: 'b * q^(n - 1)' },
lhs: 'x', rhs: '{b} * {q}^({n} - 1)', display: 'Геометрическая прогрессия: b₁ = {b}, q = {q}. Найдите {n}-й член.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Формула n-го члена геометрической прогрессии: bₙ = b₁·q^(n−1). Подставляем:', tex: 'x = {b} * {q}^({n} - 1)' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Углы (геометрия, 7 класс) ═══ */
/* третий угол треугольника */
{
id: 'ang-triangle', topic: 'g-angles', order: 1, subject: 'geometry', grade: 7, kind: 'compute',
title: 'Третий угол треугольника',
pick: { a: [20, 80], b: [20, 80] }, derive: { val: '180 - a - b' }, require: 'val >= 15 && val <= 150',
lhs: 'x', rhs: '180 - {a} - {b}', display: 'В треугольнике два угла равны {a}° и {b}°. Найдите третий угол (в градусах).',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Сумма углов треугольника равна 180°. Значит третий угол:', tex: 'x = 180 - {a} - {b}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* смежный угол */
{
id: 'ang-adjacent', topic: 'g-angles', order: 2, subject: 'geometry', grade: 7, kind: 'compute',
title: 'Смежный угол',
pick: { a: [25, 155] }, derive: { val: '180 - a' },
lhs: 'x', rhs: '180 - {a}', display: 'Один из смежных углов равен {a}°. Найдите другой смежный с ним угол.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Сумма смежных углов равна 180°. Значит:', tex: 'x = 180 - {a}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* внешний угол треугольника */
{
id: 'ang-exterior', topic: 'g-angles', order: 3, subject: 'geometry', grade: 7, kind: 'compute',
title: 'Внешний угол треугольника',
pick: { a: [20, 80], b: [20, 80] }, derive: { val: 'a + b' }, require: 'val <= 160',
lhs: 'x', rhs: '{a} + {b}', display: 'Внешний угол треугольника равен сумме двух не смежных с ним внутренних углов. Эти углы равны {a}° и {b}°. Найдите внешний угол.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Внешний угол треугольника равен сумме двух не смежных с ним внутренних углов:', tex: 'x = {a} + {b}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Теорема Пифагора (геометрия, 8 класс) ═══ */
/* гипотенуза по катетам (пифагорова тройка m,n) */
{
id: 'pyth-hyp', topic: 'g-pyth', order: 1, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Гипотенуза (Пифагор)',
pick: { m: [2, 5], n: [1, 4] }, constraint: 'm > n',
derive: { a: 'm*m - n*n', b: '2*m*n', c: 'm*m + n*n' },
lhs: 'x', rhs: 'sqrt({a}^2 + {b}^2)', display: 'Катеты прямоугольного треугольника равны {a} и {b}. Найдите гипотенузу.',
answerVar: 'x', answer: 'c', integerAnswer: true,
solution: [
{ note: 'По теореме Пифагора c² = a² + b², значит c = √(a² + b²):', tex: 'x = sqrt({a}^2 + {b}^2)' },
{ note: 'Считаем (выходит целое — это пифагорова тройка):', tex: 'x = {ans}' }
]
},
/* катет по гипотенузе и катету */
{
id: 'pyth-leg', topic: 'g-pyth', order: 2, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Катет (Пифагор)',
pick: { m: [2, 5], n: [1, 4] }, constraint: 'm > n',
derive: { a: 'm*m - n*n', b: '2*m*n', c: 'm*m + n*n' },
lhs: 'x', rhs: 'sqrt({c}^2 - {a}^2)', display: 'Гипотенуза прямоугольного треугольника {c}, один катет {a}. Найдите второй катет.',
answerVar: 'x', answer: 'b', integerAnswer: true,
solution: [
{ note: 'По теореме Пифагора b² = c² − a², значит b = √(c² a²):', tex: 'x = sqrt({c}^2 - {a}^2)' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Площади (геометрия, 8 класс) ═══ */
/* площадь прямоугольника */
{
id: 'area-rect', topic: 'g-area', order: 1, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Площадь прямоугольника',
pick: { a: [2, 16], b: [2, 16] }, derive: { val: 'a*b' },
lhs: 'x', rhs: '{a}*{b}', display: 'Стороны прямоугольника {a} и {b}. Найдите его площадь.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Площадь прямоугольника — произведение его сторон:', tex: 'x = {a}*{b}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* площадь треугольника */
{
id: 'area-triangle', topic: 'g-area', order: 2, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Площадь треугольника',
pick: { a: [2, 16], h: [2, 16] }, require: 'mod(a*h, 2) == 0',
derive: { val: 'a*h/2' },
lhs: 'x', rhs: '{a}*{h}/2', display: 'Основание треугольника {a}, высота к нему {h}. Найдите площадь.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Площадь треугольника — половина произведения основания на высоту:', tex: 'x = {a}*{h}/2' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* площадь квадрата */
{
id: 'area-square', topic: 'g-area', order: 3, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Площадь квадрата',
pick: { a: [2, 20] }, derive: { val: 'a*a' },
lhs: 'x', rhs: '{a}^2', display: 'Сторона квадрата {a}. Найдите его площадь.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Площадь квадрата — сторона, возведённая в квадрат:', tex: 'x = {a}^2' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Системы 2 линейных уравнений (7 класс) ═══
kind:'system' — ответ ПАРА (x; y). «Корень-вперёд»: берём решение (sx, sy) и
коэффициенты, выводим правые части c1/c2 так, что система имеет ровно это
решение (определитель ≠ 0). Движок рисует \begin{cases}, проверяет подстановкой. */
/* система с положительными коэффициентами */
{
id: 'sys-2x2', topic: 'systems', order: 1, subject: 'algebra', grade: 7, kind: 'system',
title: 'Система 2×2',
pick: { a1: [1, 4], b1: [1, 4], a2: [1, 4], b2: [1, 4], sx: [-6, 6], sy: [-6, 6] },
constraint: 'a1*b2 - a2*b1 != 0',
derive: { c1: 'a1*sx + b1*sy', c2: 'a2*sx + b2*sy' },
eqs: [{ lhs: '{a1}*x + {b1}*y', rhs: '{c1}' }, { lhs: '{a2}*x + {b2}*y', rhs: '{c2}' }],
answers: { x: 'sx', y: 'sy' }, answerVars: ['x', 'y'], integerAnswer: true,
solution: [
{ note: 'Исключите одну переменную: умножьте уравнения так, чтобы коэффициенты при x (или y) совпали, и сложите/вычтите — найдёте одну переменную.', tex: '' },
{ note: 'Подставьте найденное в любое уравнение. Решение системы: x = {sx}, y = {sy}.', tex: '' }
]
},
/* система с отрицательными коэффициентами (сложнее) */
{
id: 'sys-2x2-neg', topic: 'systems', order: 2, subject: 'algebra', grade: 8, kind: 'system',
title: 'Система (с отрицательными)',
pick: { a1: [-4, 4], b1: [-4, 4], a2: [-4, 4], b2: [-4, 4], sx: [-7, 7], sy: [-7, 7] },
constraint: 'a1 != 0 && b1 != 0 && a2 != 0 && b2 != 0 && a1*b2 - a2*b1 != 0',
derive: { c1: 'a1*sx + b1*sy', c2: 'a2*sx + b2*sy' },
eqs: [{ lhs: '{a1}*x + {b1}*y', rhs: '{c1}' }, { lhs: '{a2}*x + {b2}*y', rhs: '{c2}' }],
answers: { x: 'sx', y: 'sy' }, answerVars: ['x', 'y'], integerAnswer: true,
solution: [
{ note: 'Будьте внимательны со знаками. Исключите переменную методом сложения, найдите одну, подставьте во второе уравнение.', tex: '' },
{ note: 'Решение системы: x = {sx}, y = {sy}.', tex: '' }
]
},
/* ═══ Тема: Задачи (текстовые, параметрические — 7 класс) ═══
kind:'compute' — условие в display, lhs:'x'/rhs:<формула> для проверки. */
/* путь = скорость × время */
{
id: 'app-move-dist', topic: 'applied', order: 1, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Путь (движение)',
pick: { v: [10, 90], t: [2, 9] }, derive: { val: 'v*t' },
lhs: 'x', rhs: '{v}*{t}', display: 'Автомобиль ехал {t} ч со скоростью {v} км/ч. Какой путь он проехал (в км)?',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Путь равен произведению скорости на время:', tex: 'x = {v}*{t}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* время = путь / скорость */
{
id: 'app-move-time', topic: 'applied', order: 2, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Время (движение)',
pick: { v: [10, 90], t: [2, 9] }, derive: { S: 'v*t', val: 't' },
lhs: 'x', rhs: '{S}/{v}', display: 'Расстояние между городами {S} км. Автомобиль едет со скоростью {v} км/ч. За сколько часов он доедет?',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Время равно пути, делённому на скорость:', tex: 'x = {S}/{v}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* скорость = путь / время */
{
id: 'app-move-speed', topic: 'applied', order: 3, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Скорость (движение)',
pick: { v: [10, 90], t: [2, 9] }, derive: { S: 'v*t', val: 'v' },
lhs: 'x', rhs: '{S}/{t}', display: 'Поезд прошёл {S} км за {t} ч. Найдите его среднюю скорость (км/ч).',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Скорость равна пути, делённому на время:', tex: 'x = {S}/{t}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* содержание вещества в сплаве (проценты) */
{
id: 'app-alloy', topic: 'applied', order: 4, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Сплав (проценты)',
pick: { mfac: [1, 9], pidx: [1, 9] }, derive: { m: 'mfac*10', p: 'pidx*10', val: 'mfac*pidx' },
lhs: 'x', rhs: '{m}*{p}/100', display: 'Сплав массой {m} кг содержит {p}% меди. Сколько килограммов меди в сплаве?',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Масса меди = масса сплава × процент ÷ 100:', tex: 'x = {m}*{p}/100' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* цена со скидкой */
{
id: 'app-discount', topic: 'applied', order: 5, subject: 'algebra', grade: 7, kind: 'compute',
title: 'Цена со скидкой',
pick: { pbase: [5, 30], didx: [1, 5] }, derive: { price: 'pbase*10', d: 'didx*10', val: 'pbase*(10 - didx)' },
lhs: 'x', rhs: '{price}*(100 - {d})/100', display: 'Товар стоил {price} руб. Скидка {d}%. Сколько он стоит после скидки (в рублях)?',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Новая цена = старая × (100 − скидка) ÷ 100:', tex: 'x = {price}*(100 - {d})/100' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Площади (дополнение к g-area): трапеция, параллелограмм, ромб ═══ */
/* площадь трапеции */
{
id: 'area-trapezoid', topic: 'g-area', order: 4, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Площадь трапеции',
pick: { a: [2, 14], b: [2, 14], h: [2, 12] }, require: 'mod((a + b)*h, 2) == 0',
derive: { val: '(a + b)*h/2' },
lhs: 'x', rhs: '({a} + {b})*{h}/2', display: 'Основания трапеции {a} и {b}, высота {h}. Найдите площадь.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Площадь трапеции — полусумма оснований на высоту:', tex: 'x = ({a} + {b})*{h}/2' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* площадь параллелограмма */
{
id: 'area-parallelogram', topic: 'g-area', order: 5, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Площадь параллелограмма',
pick: { a: [2, 16], h: [2, 14] }, derive: { val: 'a*h' },
lhs: 'x', rhs: '{a}*{h}', display: 'Сторона параллелограмма {a}, высота к ней {h}. Найдите площадь.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Площадь параллелограмма — сторона на высоту к ней:', tex: 'x = {a}*{h}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* площадь ромба по диагоналям */
{
id: 'area-rhombus', topic: 'g-area', order: 6, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Площадь ромба',
pick: { d1: [2, 16], d2: [2, 16] }, require: 'mod(d1*d2, 2) == 0',
derive: { val: 'd1*d2/2' },
lhs: 'x', rhs: '{d1}*{d2}/2', display: 'Диагонали ромба {d1} и {d2}. Найдите площадь.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Площадь ромба — половина произведения диагоналей:', tex: 'x = {d1}*{d2}/2' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Многоугольники (геометрия, 8 класс) ═══ */
/* сумма углов выпуклого n-угольника */
{
id: 'poly-angles-sum', topic: 'g-poly', order: 1, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Сумма углов многоугольника',
pick: { n: [3, 12] }, derive: { val: '180*(n - 2)' },
lhs: 'x', rhs: '180*({n} - 2)', display: 'Найдите сумму углов выпуклого {n}-угольника (в градусах).',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Сумма углов выпуклого n-угольника равна 180°·(n − 2):', tex: 'x = 180*({n} - 2)' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* угол правильного n-угольника */
{
id: 'poly-regular-angle', topic: 'g-poly', order: 2, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Угол правильного многоугольника',
pick: { n: [3, 20] }, require: 'mod(180*(n - 2), n) == 0',
derive: { val: '180*(n - 2)/n' },
lhs: 'x', rhs: '180*({n} - 2)/{n}', display: 'Найдите величину угла правильного {n}-угольника (в градусах).',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Угол правильного n-угольника = 180°·(n 2) ÷ n:', tex: 'x = 180*({n} - 2)/{n}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Подобие (геометрия, 8 класс) ═══ */
/* сходственная сторона по коэффициенту подобия */
{
id: 'sim-side', topic: 'g-sim', order: 1, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Сторона по коэффициенту',
pick: { a: [2, 15], k: [2, 5] }, derive: { val: 'a*k' },
lhs: 'x', rhs: '{a}*{k}', display: 'Треугольники подобны с коэффициентом {k}. Сторона первого равна {a}. Найдите сходственную сторону второго.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Сходственные стороны подобных фигур пропорциональны коэффициенту подобия:', tex: 'x = {a}*{k}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* периметр подобной фигуры */
{
id: 'sim-perimeter', topic: 'g-sim', order: 2, subject: 'geometry', grade: 8, kind: 'compute',
title: 'Периметр подобной фигуры',
pick: { p: [5, 30], k: [2, 5] }, derive: { val: 'p*k' },
lhs: 'x', rhs: '{p}*{k}', display: 'Фигуры подобны с коэффициентом {k}. Периметр первой равен {p}. Найдите периметр второй.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Периметры подобных фигур относятся как коэффициент подобия:', tex: 'x = {p}*{k}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Дроби (5–6 класс) ═══
kind:'compute'; ответ может быть дробным — ученик вводит «3/4» (SimExpr посчитает). */
/* часть от числа (целый ответ: число кратно знаменателю) */
{
id: 'frac-of-number', topic: 'fractions', order: 1, subject: 'algebra', grade: 5, kind: 'compute',
title: 'Часть от числа',
pick: { n: [2, 6], a: [1, 5], mfac: [2, 9] }, require: 'a < n',
derive: { m: 'n*mfac', val: 'mfac*a' },
lhs: 'x', rhs: '{m}*{a}/{n}', display: 'Найдите {a}/{n} от числа {m}.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Чтобы найти часть от числа, умножаем число на числитель и делим на знаменатель:', tex: 'x = {m}*{a}/{n}' },
{ note: 'Считаем:', tex: 'x = {ans}' }
]
},
/* сложение дробей с одинаковым знаменателем (ответ — дробь) */
{
id: 'frac-add-same', topic: 'fractions', order: 2, subject: 'algebra', grade: 5, kind: 'compute',
title: 'Сложение дробей',
pick: { n: [3, 9], a: [1, 6], b: [1, 6] }, require: 'a + b < 2*n',
derive: { val: '(a + b)/n' },
lhs: 'x', rhs: '({a} + {b})/{n}', display: 'Вычислите {a}/{n} + {b}/{n}. Ответ запишите дробью (например 3/4) или числом.',
answerVar: 'x', answer: 'val',
solution: [
{ note: 'При одинаковом знаменателе складываем числители, знаменатель оставляем:', tex: 'x = ({a} + {b})/{n}' },
{ note: 'Получаем значение:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Десятичные дроби (5 класс) ═══
Строим через десятые/сотые (целые ÷10, ÷100) → ответ печатается чисто. */
/* сложение десятичных */
{
id: 'dec-add', topic: 'decimals', order: 1, subject: 'algebra', grade: 5, kind: 'compute',
title: 'Сложение десятичных',
pick: { a: [1, 9], b: [1, 9] }, derive: { da: 'a/10', db: 'b/10', val: '(a + b)/10' },
lhs: 'x', rhs: '({a} + {b})/10', display: 'Вычислите {da} + {db}.',
answerVar: 'x', answer: 'val',
solution: [
{ note: 'Складываем десятичные дроби поразрядно (запятая под запятой):', tex: 'x = {da} + {db}' },
{ note: 'Получаем:', tex: 'x = {ans}' }
]
},
/* вычитание десятичных */
{
id: 'dec-sub', topic: 'decimals', order: 2, subject: 'algebra', grade: 5, kind: 'compute',
title: 'Вычитание десятичных',
pick: { a: [2, 9], b: [1, 8] }, constraint: 'a > b', derive: { da: 'a/10', db: 'b/10', val: '(a - b)/10' },
lhs: 'x', rhs: '({a} - {b})/10', display: 'Вычислите {da} {db}.',
answerVar: 'x', answer: 'val',
solution: [
{ note: 'Вычитаем десятичные дроби поразрядно:', tex: 'x = {da} - {db}' },
{ note: 'Получаем:', tex: 'x = {ans}' }
]
},
/* умножение десятичных */
{
id: 'dec-mult', topic: 'decimals', order: 3, subject: 'algebra', grade: 5, kind: 'compute',
title: 'Умножение десятичных',
pick: { a: [1, 9], b: [1, 9] }, derive: { da: 'a/10', db: 'b/10', val: '(a*b)/100' },
lhs: 'x', rhs: '({a}*{b})/100', display: 'Вычислите {da} · {db}.',
answerVar: 'x', answer: 'val',
solution: [
{ note: 'Перемножаем без запятых как целые, затем отделяем 2 знака после запятой (по сумме знаков у множителей):', tex: 'x = {da} * {db}' },
{ note: 'Получаем:', tex: 'x = {ans}' }
]
},
/* ═══ Тема: Отрицательные числа (6 класс) ═══
Словесные формулировки — без двусмысленных операторов в условии. */
/* сумма с отрицательными */
{
id: 'neg-add', topic: 'negatives', order: 1, subject: 'algebra', grade: 6, kind: 'compute',
title: 'Сумма (отрицательные)',
pick: { a: [-12, 12], b: [-12, 12] }, constraint: 'a != 0 && b != 0 && (a < 0 || b < 0)', derive: { val: 'a + b' },
lhs: 'x', rhs: '{a} + {b}', display: 'Найдите сумму чисел {a} и {b}.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Складываем с учётом знаков: при одинаковых знаках складываем модули; при разных — из большего модуля вычитаем меньший и ставим знак большего:', tex: 'x = {a} + {b}' },
{ note: 'Получаем:', tex: 'x = {ans}' }
]
},
/* разность с отрицательными */
{
id: 'neg-sub', topic: 'negatives', order: 2, subject: 'algebra', grade: 6, kind: 'compute',
title: 'Разность (отрицательные)',
pick: { a: [-12, 12], b: [-12, 12] }, constraint: 'a != 0 && b != 0 && (a < 0 || b < 0)', derive: { val: 'a - b' },
lhs: 'x', rhs: '{a} - ({b})', display: 'Из числа {a} вычтите {b}.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Вычесть число — значит прибавить ему противоположное:', tex: 'x = {a} - ({b})' },
{ note: 'Получаем:', tex: 'x = {ans}' }
]
},
/* произведение с отрицательными */
{
id: 'neg-mult', topic: 'negatives', order: 3, subject: 'algebra', grade: 6, kind: 'compute',
title: 'Произведение (отрицательные)',
pick: { a: [-9, 9], b: [-9, 9] }, constraint: 'a != 0 && b != 0 && (a < 0 || b < 0)', derive: { val: 'a*b' },
lhs: 'x', rhs: '{a}*{b}', display: 'Найдите произведение чисел {a} и {b}.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Перемножаем модули; знак минус — если множители разных знаков, плюс — если одинаковых:', tex: 'x = {a}*{b}' },
{ note: 'Получаем:', tex: 'x = {ans}' }
]
}
];
// Структурная сложность генератора (1 — простейшая форма, 3 — больше действий /
// скобки / дроби / переменная в обеих частях). Определяет, какой ВАРИАНТ внутри
// темы даётся на выбранном уровне сложности (не просто масштаб чисел).
var LEVELS = {
// Уравнения: ax+b=c → скобки/обе части/дроби → (ax+b)/c=d
'lin-basic': 1, 'lin-paren': 2, 'lin-both-sides': 2, 'lin-frac-denom': 2,
'lin-coef-frac': 2, 'lin-paren-both': 3, 'lin-frac-eq': 3,
// Пропорции
'prop-x-right': 1, 'prop-x-left': 1, 'prop-x-denom': 2,
// Проценты
'pct-of': 1, 'pct-what': 2, 'pct-whole': 2,
// Упрощение
'simp-like': 1, 'simp-expand': 2,
// Степени
'pow-eval': 1, 'pow-mult': 2, 'pow-pow': 3,
// Формулы сокр. умножения
'sq-sum': 2, 'sq-diff': 2, 'diff-sq': 3,
// Неравенства (смена знака — сложнее)
'ineq-lt': 1, 'ineq-ge': 1, 'ineq-flip': 3,
// Системы 2 уравнений
'sys-2x2': 2, 'sys-2x2-neg': 3,
// Задачи (текстовые)
'app-move-dist': 1, 'app-move-speed': 1, 'app-move-time': 2, 'app-alloy': 2, 'app-discount': 2,
// Квадратные
'quad-diff': 2, 'quad-factored': 3,
// Прогрессии
'prog-arith-term': 2, 'prog-geom-term': 3,
// Геометрия — Углы
'ang-adjacent': 1, 'ang-triangle': 2, 'ang-exterior': 2,
// Геометрия — Пифагор
'pyth-hyp': 2, 'pyth-leg': 3,
// Геометрия — Площади
'area-square': 1, 'area-rect': 1, 'area-triangle': 2,
'area-parallelogram': 2, 'area-trapezoid': 3, 'area-rhombus': 2,
// Геометрия — Многоугольники / Подобие
'poly-angles-sum': 1, 'poly-regular-angle': 2, 'sim-side': 1, 'sim-perimeter': 2,
// Дроби / Десятичные / Отрицательные
'frac-of-number': 1, 'frac-add-same': 2,
'dec-add': 1, 'dec-sub': 1, 'dec-mult': 2,
'neg-add': 1, 'neg-sub': 2, 'neg-mult': 2
};
GENERATORS.forEach(function (g) { g.level = LEVELS[g.id] || 1; });
function get(id) {
for (var i = 0; i < GENERATORS.length; i++) if (GENERATORS[i].id === id) return GENERATORS[i];
return null;
}
function byTopic(key) {
return GENERATORS.filter(function (g) { return g.topic === key; })
.sort(function (a, b) { return (a.order || 0) - (b.order || 0); });
}
global.TrainerGenerators = {
list: function () { return GENERATORS.slice(); },
topics: function () { return TOPICS.slice(); },
byTopic: byTopic,
get: get,
GENERATORS: GENERATORS,
TOPICS: TOPICS
};
})(typeof window !== 'undefined' ? window : globalThis);