1868e6cb9b
Вторая волна плана v4. Все compute, «корень-вперёд» → чистые целые ответы, пошаговые решения; правок движка/страницы нет. Пропорции (proportions): prop-direct-word (прямая, цена/кол-во), prop-inverse-word (обратная, рабочие/дни), prop-scale-map (масштаб карты), prop-compound (тройная), prop-share-ratio (деление в отношении a:b). Проценты (percents): pct-increase (+p%), pct-decrease (−p%), pct-change (на сколько % выросло), pct-simple-interest (простые проценты), pct-compound-2y (сложные, 2 года), pct-restore-before (исходное до повышения — обратный процент). Текстовые (applied): app-meet (встречное), app-overtake (вдогонку), app-upstream (против течения), app-work-joint (совместная работа), app-mix-blend (концентрация смеси), app-profit-pct (прибыль в %). Итого 96 генераторов. Смоук 16508 проверок (каждый ген: инстанс/самопроверка/приём канон.ответа/отказ неверного/все шаги→LaTeX); геометрия не задета (6968/0). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1688 lines
103 KiB
JavaScript
1688 lines
103 KiB
JavaScript
'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: 'gcd-lcm', label: 'НОД и НОК', subject: 'algebra', grade: 5, order: 1.4 },
|
||
{ 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 },
|
||
{ key: 'g-circle', label: 'Окружность', subject: 'geometry', grade: 9, order: 17 }
|
||
];
|
||
|
||
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: 'Слагаемые {a}x и {b}x подобны (одинаковая буквенная часть x). Складываем коэффициенты: {a} + {b} = {s}.', tex: '{a}x + {b}x' },
|
||
{ note: 'Получаем:', tex: '{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} на каждое слагаемое в скобке: {a}·x и {a}·{b}.', tex: '{a}(x + {b})' },
|
||
{ note: 'Получаем:', tex: '{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: 'Основание одинаковое (x) — при умножении степеней показатели складываются: {a} + {b} = {s}.', tex: 'x^{a} * x^{b}' },
|
||
{ note: 'Получаем:', tex: '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}' },
|
||
{ note: 'Получаем:', tex: '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: 'Это квадрат суммы. Формула: (a + b)² = a² + 2ab + b² (здесь a = x, b = {a}).', tex: '(x + {a})^2' },
|
||
{ note: 'Раскрываем и приводим к стандартному виду:', tex: '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: 'Это квадрат разности. Формула: (a − b)² = a² − 2ab + b² (здесь a = x, b = {a}).', tex: '(x - {a})^2' },
|
||
{ note: 'Раскрываем и приводим к стандартному виду:', tex: '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: 'Произведение разности и суммы — формула разности квадратов: (a − b)(a + b) = a² − b².', tex: '(x - {a})*(x + {a})' },
|
||
{ note: 'Получаем:', tex: '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: 'Третий угол треугольника',
|
||
figure: { type: 'triangle-angles', angA: 'a', angB: 'b' },
|
||
figurePrompt: 'Найдите неизвестный угол треугольника (в градусах).',
|
||
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: 'Смежный угол',
|
||
figure: { type: 'adjacent-angles', ang: 'a' },
|
||
figurePrompt: 'Найдите неизвестный угол (в градусах).',
|
||
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: 'Внешний угол треугольника',
|
||
figure: { type: 'triangle-angles', angA: 'a', angB: 'b', ext: true },
|
||
figurePrompt: 'Найдите внешний угол треугольника (в градусах).',
|
||
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: 'Гипотенуза (Пифагор)',
|
||
figure: { type: 'right-triangle', a: 'a', b: 'b', c: 'c', unknown: 'c' },
|
||
figurePrompt: 'Найдите гипотенузу прямоугольного треугольника (отмечена «?»).',
|
||
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: 'Катет (Пифагор)',
|
||
figure: { type: 'right-triangle', a: 'a', b: 'b', c: 'c', unknown: 'b' },
|
||
figurePrompt: 'Найдите неизвестный катет (отмечен «?»).',
|
||
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: 'Площадь прямоугольника',
|
||
figure: { type: 'rectangle', w: 'a', h: 'b' },
|
||
figurePrompt: 'Найдите площадь прямоугольника.',
|
||
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: 'Площадь треугольника',
|
||
figure: { type: 'triangle-base-height', base: 'a', height: 'h' },
|
||
figurePrompt: 'Найдите площадь треугольника.',
|
||
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: 'Площадь квадрата',
|
||
figure: { type: 'square', a: 'a' },
|
||
figurePrompt: 'Найдите площадь квадрата.',
|
||
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: [2, 4], b1: [2, 4], a2: [2, 4], b2: [2, 4], sx: [-6, 6], sy: [-6, 6] },
|
||
constraint: 'a1*b2 - a2*b1 != 0',
|
||
derive: { c1: 'a1*sx + b1*sy', c2: 'a2*sx + b2*sy', coefY: 'b1*a2 - b2*a1', rhsY: 'c1*a2 - c2*a1' },
|
||
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: умножим первое уравнение на {a2}, а второе — на {a1}.', tex: '' },
|
||
{ note: 'Вычтем из первого уравнения второе — слагаемые с x сократятся, останется только y:', tex: '{coefY}*y = {rhsY}' },
|
||
{ note: 'Разделим обе части на коэффициент при y:', tex: 'y = {sy}' },
|
||
{ note: 'Подставим y = {sy} в первое уравнение системы:', tex: '{a1}*x + {b1}*{sy} = {c1}' },
|
||
{ note: 'Решим его относительно x:', tex: 'x = {sx}' },
|
||
{ 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: 'abs(a1) >= 2 && abs(b1) >= 2 && abs(a2) >= 2 && abs(b2) >= 2 && a1*b2 - a2*b1 != 0',
|
||
derive: { c1: 'a1*sx + b1*sy', c2: 'a2*sx + b2*sy', coefY: 'b1*a2 - b2*a1', rhsY: 'c1*a2 - c2*a1' },
|
||
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: умножим первое уравнение на {a2}, второе — на {a1}.', tex: '' },
|
||
{ note: 'Вычтем из первого уравнения второе — переменная x исключается:', tex: '{coefY}*y = {rhsY}' },
|
||
{ note: 'Разделим обе части на коэффициент при y:', tex: 'y = {sy}' },
|
||
{ note: 'Подставим y = {sy} в первое уравнение системы:', tex: '{a1}*x + {b1}*{sy} = {c1}' },
|
||
{ note: 'Найдём x:', tex: 'x = {sx}' },
|
||
{ 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: 'Площадь трапеции',
|
||
figure: { type: 'trapezoid', bottom: 'a', top: 'b', height: 'h' },
|
||
figurePrompt: 'Найдите площадь трапеции.',
|
||
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: 'Площадь параллелограмма',
|
||
figure: { type: 'parallelogram', base: 'a', height: 'h' },
|
||
figurePrompt: 'Найдите площадь параллелограмма.',
|
||
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: 'Площадь ромба',
|
||
figure: { type: 'rhombus', d1: 'd1', d2: 'd2' },
|
||
figurePrompt: 'Найдите площадь ромба.',
|
||
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: 'Сумма углов многоугольника',
|
||
figure: { type: 'regular-polygon', n: 'n' },
|
||
figurePrompt: 'Найдите сумму углов многоугольника на чертеже (в градусах).',
|
||
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: 'Угол правильного многоугольника',
|
||
figure: { type: 'regular-polygon', n: 'n', markAngle: true },
|
||
figurePrompt: 'Найдите угол правильного многоугольника на чертеже (в градусах).',
|
||
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: 'Сторона по коэффициенту',
|
||
figure: { type: 'two-similar', side: 'a', k: 'k', mode: 'side' },
|
||
figurePrompt: 'Найдите сходственную сторону подобного треугольника (отмечена «?»).',
|
||
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: 'Периметр подобной фигуры',
|
||
figure: { type: 'two-similar', perim: 'p', k: 'k', mode: 'perimeter' },
|
||
figurePrompt: 'Найдите периметр подобной фигуры (отмечена «?»).',
|
||
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–6 класс) ═══
|
||
Оба числа строим из ДВУХ простых множителей p<q (из {2,3,5,7}) с показателями
|
||
1..2: a = p^e1·q^f1, b = p^e2·q^f2. Тогда разложение известно из параметров →
|
||
решение показывает СТАНДАРТНЫЙ школьный метод (разложение на простые множители):
|
||
НОД = общие множители в НАИМЕНЬШИХ степенях (min показателей),
|
||
НОК = все множители в НАИБОЛЬШИХ степенях (max показателей).
|
||
gcd/lcm — функции SimExpr, дают эталон для проверки; min/max — показатели для шагов.
|
||
(exprToLatex убирает ^1 → разложение печатается красиво: 2^2·3, а не 2^2·3^1.) */
|
||
|
||
/* наибольший общий делитель — через разложение на простые множители */
|
||
{
|
||
id: 'gcd-pair', topic: 'gcd-lcm', order: 1, subject: 'algebra', grade: 5, kind: 'compute',
|
||
title: 'НОД двух чисел',
|
||
pick: { g: [2, 9], m: [2, 8], n: [2, 8] }, constraint: 'm != n',
|
||
derive: { a: 'g*m', b: 'g*n', val: 'gcd(a, b)' },
|
||
require: 'a <= 90 && b <= 90',
|
||
factorize: [{ name: 'aFac', of: 'a' }, { name: 'bFac', of: 'b' }, { name: 'dFac', of: 'gcd(a, b)' }],
|
||
lhs: 'x', rhs: 'gcd({a}, {b})', display: 'Найдите наибольший общий делитель (НОД) чисел {a} и {b}.',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Разложим {a} на простые множители:', tex: '{a} = {aFac}' },
|
||
{ note: 'Разложим {b} на простые множители:', tex: '{b} = {bFac}' },
|
||
{ note: 'НОД — произведение ОБЩИХ множителей (повторяющиеся берём в наименьшем количестве):', tex: 'x = {dFac}' },
|
||
{ note: 'Перемножаем:', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* наименьшее общее кратное — через разложение на простые множители */
|
||
{
|
||
id: 'lcm-pair', topic: 'gcd-lcm', order: 2, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'НОК двух чисел',
|
||
pick: { g: [2, 9], m: [2, 8], n: [2, 8] }, constraint: 'm != n',
|
||
derive: { a: 'g*m', b: 'g*n', val: 'lcm(a, b)' },
|
||
require: 'a <= 60 && b <= 60 && lcm(a, b) <= 240',
|
||
factorize: [{ name: 'aFac', of: 'a' }, { name: 'bFac', of: 'b' }, { name: 'kFac', of: 'lcm(a, b)' }],
|
||
lhs: 'x', rhs: 'lcm({a}, {b})', display: 'Найдите наименьшее общее кратное (НОК) чисел {a} и {b}.',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Разложим {a} на простые множители:', tex: '{a} = {aFac}' },
|
||
{ note: 'Разложим {b} на простые множители:', tex: '{b} = {bFac}' },
|
||
{ note: 'НОК — произведение ВСЕХ множителей (общие берём в наибольшем количестве):', tex: 'x = {kFac}' },
|
||
{ 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}' }
|
||
]
|
||
},
|
||
|
||
/* ═══ Тема: Окружность (геометрия, 9 класс) ═══
|
||
Считаем с π ≈ 3,14 (как в учебниках) → ответ — КОНЕЧНАЯ десятичная дробь,
|
||
ученик вводит её (SimExpr принимает «31.4»). Чертёж показывает радиус/диаметр/угол. */
|
||
|
||
/* длина окружности по радиусу: C = 2πr */
|
||
{
|
||
id: 'circ-length', topic: 'g-circle', order: 1, subject: 'geometry', grade: 9, kind: 'compute',
|
||
title: 'Длина окружности',
|
||
figure: { type: 'circle', r: 'r', show: 'radius' },
|
||
figurePrompt: 'Найдите длину окружности (π ≈ 3,14).',
|
||
pick: { r: [1, 20] }, derive: { val: '2*3.14*r' },
|
||
lhs: 'x', rhs: '2*3.14*{r}', display: 'Радиус окружности равен {r}. Найдите длину окружности (π ≈ 3,14).',
|
||
answerVar: 'x', answer: 'val',
|
||
solution: [
|
||
{ note: 'Длина окружности вычисляется по формуле C = 2πr. Подставляем r = {r} и π ≈ 3,14:', tex: 'x = 2*3.14*{r}' },
|
||
{ note: 'Считаем:', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* длина окружности по диаметру: C = πd */
|
||
{
|
||
id: 'circ-diam', topic: 'g-circle', order: 2, subject: 'geometry', grade: 9, kind: 'compute',
|
||
title: 'Длина по диаметру',
|
||
figure: { type: 'circle', d: 'd', show: 'diameter' },
|
||
figurePrompt: 'Найдите длину окружности (π ≈ 3,14).',
|
||
pick: { d: [2, 30] }, derive: { val: '3.14*d' },
|
||
lhs: 'x', rhs: '3.14*{d}', display: 'Диаметр окружности равен {d}. Найдите длину окружности (π ≈ 3,14).',
|
||
answerVar: 'x', answer: 'val',
|
||
solution: [
|
||
{ note: 'Длину окружности можно найти через диаметр: C = πd. Подставляем d = {d} и π ≈ 3,14:', tex: 'x = 3.14*{d}' },
|
||
{ note: 'Считаем:', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* площадь круга: S = πr² */
|
||
{
|
||
id: 'circ-area', topic: 'g-circle', order: 3, subject: 'geometry', grade: 9, kind: 'compute',
|
||
title: 'Площадь круга',
|
||
figure: { type: 'circle', r: 'r', show: 'area' },
|
||
figurePrompt: 'Найдите площадь круга (π ≈ 3,14).',
|
||
pick: { r: [1, 15] }, derive: { val: '3.14*r^2' },
|
||
lhs: 'x', rhs: '3.14*{r}^2', display: 'Радиус круга равен {r}. Найдите его площадь (π ≈ 3,14).',
|
||
answerVar: 'x', answer: 'val',
|
||
solution: [
|
||
{ note: 'Площадь круга вычисляется по формуле S = πr². Подставляем r = {r} и π ≈ 3,14:', tex: 'x = 3.14*{r}^2' },
|
||
{ note: 'Считаем:', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* длина дуги: L = (n/360)·2πr; n = 45·k, требуем конечную дробь (r·k чётно) */
|
||
{
|
||
id: 'circ-arc', topic: 'g-circle', order: 4, subject: 'geometry', grade: 9, kind: 'compute',
|
||
title: 'Длина дуги',
|
||
figure: { type: 'circle-arc', r: 'r', angle: 'n' },
|
||
figurePrompt: 'Найдите длину дуги (π ≈ 3,14).',
|
||
pick: { r: [3, 12], k: [1, 7] }, require: 'mod(r*k, 2) == 0',
|
||
derive: { n: '45*k', val: '45*k/360*2*3.14*r' },
|
||
lhs: 'x', rhs: '{n}/360*2*3.14*{r}', display: 'Дуга окружности радиуса {r} опирается на центральный угол {n}°. Найдите длину дуги (π ≈ 3,14).',
|
||
answerVar: 'x', answer: 'val',
|
||
solution: [
|
||
{ note: 'Длина дуги — это часть длины окружности: L = (n/360)·2πr. Здесь n = {n}°, r = {r}, π ≈ 3,14:', tex: 'x = {n}/360*2*3.14*{r}' },
|
||
{ note: 'Считаем:', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
V4.1 — Группа 1 (линейные): новые формы и формулировки. Все «корень-вперёд».
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
|
||
/* ── Уравнения ── */
|
||
|
||
/* ax + b = cx + d с гарантированным делением на (a−c)≥2 */
|
||
{
|
||
id: 'lin-both-frac', topic: 'linear-eq', order: 8, subject: 'algebra', grade: 7,
|
||
title: 'ax + b = cx + d (с делением)',
|
||
pick: { a: [5, 9], c: [1, 4], b: [1, 12], root: [-7, 7] },
|
||
constraint: 'a - c >= 2', 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: 'Приводим подобные.', 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 в знаменателе */
|
||
{
|
||
id: 'lin-x-denom', topic: 'linear-eq', order: 9, subject: 'algebra', grade: 8,
|
||
title: 'a/(x + b) = c',
|
||
pick: { c: [2, 6], b: [-5, 8], root: [-7, 9] },
|
||
require: 'root + b != 0 && root != 0',
|
||
derive: { a: 'c*(root + b)', rb: 'root + b' },
|
||
lhs: '{a}/(x + {b})', rhs: '{c}', display: '{a}/(x + {b}) = {c}',
|
||
answerVar: 'x', answer: 'root', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Знаменатель x + {b} не равен нулю. Умножим обе части на него.', tex: '{a} = {c}*(x + {b})' },
|
||
{ note: 'Разделим обе части на {c}.', tex: 'x + {b} = {rb}' },
|
||
{ note: 'Перенесём {b} вправо со сменой знака.', tex: 'x = {ans}' },
|
||
{ note: 'Проверка: подставляем корень в исходную дробь.', tex: '{a}/({ans} + {b}) = {c}' }
|
||
]
|
||
},
|
||
|
||
/* k/x = c — обратная пропорция */
|
||
{
|
||
id: 'lin-k-over-x', topic: 'linear-eq', order: 10, subject: 'algebra', grade: 8,
|
||
title: 'k/x = c',
|
||
pick: { c: [2, 9], root: [-9, 9] },
|
||
require: 'root != 0',
|
||
derive: { k: 'c*root' },
|
||
lhs: '{k}/x', rhs: '{c}', display: '{k}/x = {c}',
|
||
answerVar: 'x', answer: 'root', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Умножим обе части на x, чтобы убрать дробь.', tex: '{k} = {c}*x' },
|
||
{ note: 'Разделим обе части на {c}.', tex: 'x = {k} / {c}' },
|
||
{ note: 'Получаем корень.', tex: 'x = {ans}' },
|
||
{ note: 'Проверка: подставляем корень.', tex: '{k}/({ans}) = {c}' }
|
||
]
|
||
},
|
||
|
||
/* |ax + b| = c — два корня */
|
||
{
|
||
id: 'lin-abs', topic: 'linear-eq', order: 11, subject: 'algebra', grade: 8, kind: 'roots',
|
||
title: '|ax + b| = c',
|
||
pick: { a: [1, 5], r1: [-7, 3], r2: [-2, 8] },
|
||
constraint: 'r2 > r1',
|
||
derive: { b: '-a*(r1 + r2)/2', c: 'a*(r2 - r1)/2' },
|
||
require: 'mod(a*(r1 + r2), 2) == 0 && c > 0',
|
||
lhs: 'abs({a}*x + {b})', rhs: '{c}', display: '|{a}x + {b}| = {c}',
|
||
answerVar: 'x', answers: ['r1', 'r2'], integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Модуль равен {c}, значит выражение под модулем равно {c} или −{c}. Рассмотрим два случая.', tex: '' },
|
||
{ note: 'Первый случай — выражение равно {c}:', tex: '{a}*x + {b} = {c}' },
|
||
{ note: 'Решаем и получаем корень:', tex: 'x = {r2}' },
|
||
{ note: 'Второй случай — выражение равно −{c}:', tex: '{a}*x + {b} = -{c}' },
|
||
{ note: 'Решаем и получаем второй корень:', tex: 'x = {r1}' }
|
||
]
|
||
},
|
||
|
||
/* (ax + b)/c = (dx + g)/f — дробь = дробь (крест-накрест) */
|
||
{
|
||
id: 'lin-frac-eq-frac', topic: 'linear-eq', order: 12, subject: 'algebra', grade: 8,
|
||
title: '(ax + b)/c = (dx + g)/f',
|
||
pick: { a: [2, 5], c: [2, 4], d: [1, 4], f: [2, 4], b: [1, 9], root: [-5, 6] },
|
||
constraint: 'a*f != c*d',
|
||
require: 'mod(f*(a*root + b) - c*d*root, c) == 0 && root != 0',
|
||
derive: { g: '(f*(a*root + b) - c*d*root)/c', fa: 'f*a', fb: 'f*b', cd: 'c*d', cg: 'c*g', cross: 'f*a - c*d', rc: '(f*a - c*d)*root' },
|
||
lhs: '({a}*x + {b})/{c}', rhs: '({d}*x + {g})/{f}', display: '({a}x + {b})/{c} = ({d}x + {g})/{f}',
|
||
answerVar: 'x', answer: 'root', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Перед нами равенство двух дробей. Умножаем крест-накрест: числитель левой на знаменатель правой и наоборот.', tex: '{f}*({a}*x + {b}) = {c}*({d}*x + {g})' },
|
||
{ note: 'Раскрываем скобки.', tex: '{fa}*x + {fb} = {cd}*x + {cg}' },
|
||
{ note: 'Собираем x слева, числа справа.', tex: '{cross}*x = {rc}' },
|
||
{ note: 'Делим на коэффициент при x.', tex: 'x = {ans}' },
|
||
{ note: 'Проверка: при найденном x обе дроби равны.', tex: '({a}*({ans}) + {b})/{c} = ({d}*({ans}) + {g})/{f}' }
|
||
]
|
||
},
|
||
|
||
/* a(b(x + c) + d) = e — вложенные скобки */
|
||
{
|
||
id: 'lin-nested-paren', topic: 'linear-eq', order: 13, subject: 'algebra', grade: 8,
|
||
title: 'a(b(x + c) + d) = e',
|
||
pick: { a: [2, 4], b: [2, 4], c: [-4, 6], d: [1, 8], root: [-5, 6] },
|
||
require: 'root != 0',
|
||
derive: { ev: 'a*(b*(root + c) + d)', inner: 'b*(root + c) + d', inner2: 'b*(root + c)', rootc: 'root + c' },
|
||
lhs: '{a}*({b}*(x + {c}) + {d})', rhs: '{ev}', display: '{a}({b}(x + {c}) + {d}) = {ev}',
|
||
answerVar: 'x', answer: 'root', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Снимаем внешний множитель {a}: делим обе части на {a}.', tex: '{b}*(x + {c}) + {d} = {inner}' },
|
||
{ note: 'Переносим {d} вправо.', tex: '{b}*(x + {c}) = {inner2}' },
|
||
{ note: 'Делим на {b}.', tex: 'x + {c} = {rootc}' },
|
||
{ note: 'Переносим {c} и получаем корень.', tex: 'x = {ans}' },
|
||
{ note: 'Проверка: подставляем корень во вложенные скобки.', tex: '{a}*({b}*({ans} + {c}) + {d}) = {ev}' }
|
||
]
|
||
},
|
||
|
||
/* ax + b = mx — «выразите x» (буквенный коэффициент как параметр) */
|
||
{
|
||
id: 'lin-literal', topic: 'linear-eq', order: 14, subject: 'algebra', grade: 8,
|
||
title: 'ax + b = mx (выразите x)',
|
||
pick: { a: [2, 5], gap: [2, 6], root: [2, 8] },
|
||
derive: { m: 'a + gap', b: 'gap*root', mma: 'gap' },
|
||
lhs: '{a}*x + {b}', rhs: '{m}*x', display: '{a}x + {b} = {m}x',
|
||
answerVar: 'x', answer: 'root', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Соберём слагаемые с x в одной части: перенесём {a}x вправо, число оставим слева.', tex: '{b} = ({m} - {a})*x' },
|
||
{ note: 'Приводим подобные (коэффициент при x).', tex: '{b} = {mma}*x' },
|
||
{ note: 'Делим обе части на {mma}.', tex: 'x = {b} / {mma}' },
|
||
{ note: 'Получаем корень.', tex: 'x = {ans}' },
|
||
{ note: 'Проверка: подставляем корень.', tex: '{a}*({ans}) + {b} = {m}*({ans})' }
|
||
]
|
||
},
|
||
|
||
/* ── Неравенства ── */
|
||
|
||
/* ax + b < cx + d, a>c — знак сохраняется */
|
||
{
|
||
id: 'ineq-both-sides', topic: 'inequalities', order: 4, subject: 'algebra', grade: 8, kind: 'inequality',
|
||
title: 'ax + b < cx + d',
|
||
pick: { a: [3, 7], c: [1, 4], b: [1, 12], root: [-6, 8] },
|
||
constraint: 'a - c >= 2',
|
||
derive: { d: '(a - c)*root + b', amc: 'a - c', dmb: '(a - c)*root' },
|
||
lhs: '{a}*x + {b}', rhs: '{c}*x + {d}', dispOp: '<', relOp: '<', bound: 'root',
|
||
answerVar: 'x',
|
||
solution: [
|
||
{ note: 'Собираем x слева, числа справа (со сменой знака при переносе).', tex: '({a} - {c})x < {d} - {b}' },
|
||
{ note: 'Приводим подобные.', tex: '{amc}x < {dmb}' },
|
||
{ note: 'Делим на {amc} — число положительное, знак неравенства сохраняется.', tex: 'x < {root}' }
|
||
]
|
||
},
|
||
|
||
/* ax + b ≥ cx + d, c>a — смена знака */
|
||
{
|
||
id: 'ineq-both-flip', topic: 'inequalities', order: 5, subject: 'algebra', grade: 8, kind: 'inequality',
|
||
title: 'ax + b ≥ cx + d (смена знака)',
|
||
pick: { a: [1, 4], c: [3, 7], b: [1, 12], root: [-6, 8] },
|
||
constraint: 'c - a >= 2',
|
||
derive: { d: '(a - c)*root + b', amc: 'a - c', dmb: '(a - c)*root' },
|
||
lhs: '{a}*x + {b}', rhs: '{c}*x + {d}', dispOp: '>=', relOp: '<=', bound: 'root',
|
||
answerVar: 'x',
|
||
solution: [
|
||
{ note: 'Собираем x слева, числа справа.', tex: '({a} - {c})x >= {d} - {b}' },
|
||
{ note: 'Приводим подобные — коэффициент при x отрицательный.', tex: '{amc}*x >= {dmb}' },
|
||
{ note: 'Делим на отрицательное число {amc} — знак неравенства МЕНЯЕТСЯ.', tex: 'x <= {root}' }
|
||
]
|
||
},
|
||
|
||
/* a(x + b) > c — скобка в неравенстве */
|
||
{
|
||
id: 'ineq-paren', topic: 'inequalities', order: 6, subject: 'algebra', grade: 8, kind: 'inequality',
|
||
title: 'a(x + b) > c',
|
||
pick: { a: [2, 6], b: [1, 8], root: [-5, 8] },
|
||
derive: { c: 'a*(root + b)', rootb: 'root + b' },
|
||
lhs: '{a}*(x + {b})', rhs: '{c}', dispOp: '>', relOp: '>', bound: 'root',
|
||
answerVar: 'x',
|
||
solution: [
|
||
{ note: 'Делим обе части на {a} (положительное) — знак сохраняется.', tex: 'x + {b} > {rootb}' },
|
||
{ note: 'Переносим {b} вправо.', tex: 'x > {root}' }
|
||
]
|
||
},
|
||
|
||
/* Сколько целых решений у lo < x ≤ hi (двойное неравенство через compute) */
|
||
{
|
||
id: 'ineq-count-int', topic: 'inequalities', order: 7, subject: 'algebra', grade: 8, kind: 'compute',
|
||
title: 'Число целых решений',
|
||
pick: { lo: [-6, 3], span: [2, 8] },
|
||
derive: { hi: 'lo + span', val: 'span' },
|
||
lhs: 'x', rhs: '{hi} - {lo}', display: 'Сколько целых чисел x удовлетворяют условию {lo} < x ≤ {hi}?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Целые решения — это {lo}+1, {lo}+2, …, {hi}. Их количество равно {hi} − {lo}.', tex: 'x = {hi} - {lo}' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* ── Системы ── */
|
||
|
||
/* x + y = S, x − y = D — сумма и разность */
|
||
{
|
||
id: 'sys-sum-diff', topic: 'systems', order: 3, subject: 'algebra', grade: 7, kind: 'system',
|
||
title: 'Система x + y = S, x − y = D',
|
||
pick: { sx: [-7, 8], sy: [-7, 8] },
|
||
derive: { S: 'sx + sy', D: 'sx - sy', twoX: '2*sx', twoY: '2*sy' },
|
||
eqs: [{ lhs: 'x + y', rhs: '{S}' }, { lhs: 'x - y', rhs: '{D}' }],
|
||
answers: { x: 'sx', y: 'sy' }, answerVars: ['x', 'y'], integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Сложим уравнения почленно — переменная y исключается.', tex: '2*x = {twoX}' },
|
||
{ note: 'Находим x.', tex: 'x = {sx}' },
|
||
{ note: 'Вычтем из первого уравнения второе — исключается x.', tex: '2*y = {twoY}' },
|
||
{ note: 'Находим y.', tex: 'y = {sy}' },
|
||
{ note: 'Ответ: x = {sx}, y = {sy}.', tex: '' }
|
||
]
|
||
},
|
||
|
||
/* y = mx + k, a2·x + b2·y = c2 — метод подстановки */
|
||
{
|
||
id: 'sys-subst', topic: 'systems', order: 4, subject: 'algebra', grade: 7, kind: 'system',
|
||
title: 'Система (подстановка)',
|
||
pick: { sx: [-5, 6], sy: [-6, 7], m: [-3, 4], a2: [1, 5], b2: [1, 4] },
|
||
constraint: 'a2 + b2*m != 0',
|
||
derive: { k: 'sy - m*sx', c2: 'a2*sx + b2*sy', detc: 'a2 + b2*m', rhsx: 'c2 - b2*k' },
|
||
eqs: [{ lhs: 'y', rhs: '{m}*x + {k}' }, { lhs: '{a2}*x + {b2}*y', rhs: '{c2}' }],
|
||
answers: { x: 'sx', y: 'sy' }, answerVars: ['x', 'y'], integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Первое уравнение уже выражает y. Подставим его во второе.', tex: '{a2}*x + {b2}*({m}*x + {k}) = {c2}' },
|
||
{ note: 'Раскрываем скобки и приводим подобные при x.', tex: '{detc}*x = {rhsx}' },
|
||
{ note: 'Находим x.', tex: 'x = {sx}' },
|
||
{ note: 'Подставляем x в первое уравнение.', tex: 'y = {m}*({sx}) + {k}' },
|
||
{ note: 'Находим y.', tex: 'y = {sy}' },
|
||
{ note: 'Ответ: x = {sx}, y = {sy}.', tex: '' }
|
||
]
|
||
},
|
||
|
||
/* Текстовая задача на систему (мальчики/девочки) */
|
||
{
|
||
id: 'sys-word', topic: 'systems', order: 5, subject: 'algebra', grade: 7, kind: 'system',
|
||
title: 'Текстовая задача (система)',
|
||
pick: { sx: [5, 16], sy: [6, 18] },
|
||
constraint: 'sy > sx',
|
||
derive: { N: 'sx + sy', D: 'sy - sx', twoY: '2*sy' },
|
||
eqs: [{ lhs: 'x + y', rhs: '{N}' }, { lhs: 'y - x', rhs: '{D}' }],
|
||
display: 'В классе всего {N} учеников, причём девочек на {D} больше, чем мальчиков. Сколько мальчиков (x) и девочек (y)?',
|
||
answers: { x: 'sx', y: 'sy' }, answerVars: ['x', 'y'], integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Обозначим мальчиков за x, девочек за y. Всего учеников:', tex: 'x + y = {N}' },
|
||
{ note: 'Девочек на {D} больше, чем мальчиков:', tex: 'y - x = {D}' },
|
||
{ note: 'Сложим уравнения — найдём удвоенное число девочек.', tex: '2*y = {twoY}' },
|
||
{ note: 'Находим число девочек y.', tex: 'y = {sy}' },
|
||
{ note: 'Тогда мальчиков:', tex: 'x = {N} - {sy}' },
|
||
{ note: 'Ответ: мальчиков {sx}, девочек {sy}.', tex: '' }
|
||
]
|
||
},
|
||
|
||
/* Система 3×3 (вводный тизер) */
|
||
{
|
||
id: 'sys-3x3', topic: 'systems', order: 6, subject: 'algebra', grade: 9, kind: 'system',
|
||
title: 'Система 3×3',
|
||
pick: { sx: [-4, 5], sy: [-4, 5], sz: [-4, 5] },
|
||
derive: { S: 'sx + sy + sz', Sxy: 'sx + sy', Syz: 'sy + sz' },
|
||
eqs: [{ lhs: 'x + y + z', rhs: '{S}' }, { lhs: 'x + y', rhs: '{Sxy}' }, { lhs: 'y + z', rhs: '{Syz}' }],
|
||
answers: { x: 'sx', y: 'sy', z: 'sz' }, answerVars: ['x', 'y', 'z'], integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Вычтем из первого уравнения второе — найдём z.', tex: 'z = {S} - {Sxy}' },
|
||
{ note: 'Получаем z.', tex: 'z = {sz}' },
|
||
{ note: 'Вычтем из первого уравнения третье — найдём x.', tex: 'x = {S} - {Syz}' },
|
||
{ note: 'Получаем x.', tex: 'x = {sx}' },
|
||
{ note: 'Из второго уравнения найдём y.', tex: 'y = {Sxy} - {sx}' },
|
||
{ note: 'Ответ: x = {sx}, y = {sy}, z = {sz}.', tex: '' }
|
||
]
|
||
},
|
||
|
||
/* ═══════════════════════════════════════════════════════════════════════
|
||
V4.1 — Группа 2: пропорции, проценты, текстовые задачи. Все compute,
|
||
«корень-вперёд» → ответ — чистое целое. (t как имя param в тренажёре допустим.)
|
||
═══════════════════════════════════════════════════════════════════════ */
|
||
|
||
/* ── Пропорции (сюжетные) ── */
|
||
|
||
/* прямая пропорция: цена/количество */
|
||
{
|
||
id: 'prop-direct-word', topic: 'proportions', order: 4, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'Прямая пропорция',
|
||
pick: { u: [2, 9], n: [2, 6], m: [2, 9] }, constraint: 'm != n',
|
||
derive: { S: 'u*n', val: 'u*m' },
|
||
lhs: 'x', rhs: '{S}*{m}/{n}', display: 'За {n} тетрадей заплатили {S} руб. Сколько рублей стоят {m} таких тетрадей?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Сначала найдём цену одной тетради: делим стоимость на количество.', tex: '{S} / {n} = {u}' },
|
||
{ note: 'Тогда {m} тетрадей стоят:', tex: 'x = {u} * {m}' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* обратная пропорция: рабочие/дни */
|
||
{
|
||
id: 'prop-inverse-word', topic: 'proportions', order: 5, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'Обратная пропорция',
|
||
pick: { n: [2, 9], m: [2, 9], d2: [2, 9] }, constraint: 'n != m',
|
||
derive: { W: 'm*d2', d: 'm*d2/n', val: 'd2' },
|
||
require: 'mod(m*d2, n) == 0 && d >= 2',
|
||
lhs: 'x', rhs: '{n}*{d}/{m}', display: '{n} рабочих выполнили заказ за {d} дней. За сколько дней выполнят тот же заказ {m} рабочих?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Это обратная пропорция: общий объём работы постоянен. Считаем «рабочие-дни»: {n} · {d}.', tex: '{n} * {d} = {W}' },
|
||
{ note: 'Делим общий объём на новое число рабочих {m}.', tex: 'x = {W} / {m}' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* масштаб карты */
|
||
{
|
||
id: 'prop-scale-map', topic: 'proportions', order: 6, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'Масштаб карты',
|
||
pick: { kbase: [1, 9], a: [2, 12] },
|
||
derive: { k: 'kbase*100', val: 'a*kbase' },
|
||
lhs: 'x', rhs: '{a}*{k}/100', display: 'Масштаб карты 1 : {k}. Отрезок на карте равен {a} см. Какому расстоянию на местности это соответствует (в метрах)?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Масштаб 1 : {k} значит, что 1 см карты — это {k} см на местности. Отрезок {a} см — это {a}·{k} см.', tex: '{a} * {k}' },
|
||
{ note: 'Переводим сантиметры в метры — делим на 100.', tex: 'x = {a} * {k} / 100' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* сложная (тройная) пропорция */
|
||
{
|
||
id: 'prop-compound', topic: 'proportions', order: 7, subject: 'algebra', grade: 7, kind: 'compute',
|
||
title: 'Тройная пропорция',
|
||
pick: { r: [1, 4], n: [2, 6], d: [2, 6], m: [2, 6], e2: [2, 6] },
|
||
derive: { W: 'r*n*d', val: 'r*m*e2' },
|
||
lhs: 'x', rhs: '{W}*{m}*{e2}/({n}*{d})', display: '{n} рабочих за {d} дней изготовили {W} деталей. Сколько деталей изготовят {m} рабочих за {e2} дней при той же производительности?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Найдём, сколько деталей делает один рабочий за один день: {W} ÷ ({n}·{d}).', tex: '{W} / ({n} * {d})' },
|
||
{ note: 'Тогда {m} рабочих за {e2} дней изготовят:', tex: 'x = {W} * {m} * {e2} / ({n} * {d})' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* деление в отношении a:b */
|
||
{
|
||
id: 'prop-share-ratio', topic: 'proportions', order: 8, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'Деление в отношении',
|
||
pick: { a: [1, 7], b: [1, 7], u: [2, 20] },
|
||
derive: { S: 'u*(a + b)', val: 'u*a' },
|
||
lhs: 'x', rhs: '{S}*{a}/({a}+{b})', display: 'Сумму {S} руб разделили в отношении {a} : {b}. Сколько рублей получил первый?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Всего долей {a} + {b}. Одна доля равна {S} ÷ ({a}+{b}).', tex: '{S} / ({a} + {b}) = {u}' },
|
||
{ note: 'Первому достаётся {a} долей:', tex: 'x = {u} * {a}' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* ── Проценты ── */
|
||
|
||
/* увеличение на p% */
|
||
{
|
||
id: 'pct-increase', topic: 'percents', order: 4, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'Увеличение на p%',
|
||
pick: { abase: [1, 9], pidx: [1, 8] },
|
||
derive: { a: 'abase*100', p: 'pidx*5', val: 'abase*(100 + pidx*5)' },
|
||
lhs: 'x', rhs: '{a}*(100 + {p})/100', display: 'Цену {a} руб повысили на {p}%. Сколько рублей стала стоить вещь?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Повышение на {p}% — это умножение на (100 + {p})/100.', tex: 'x = {a} * (100 + {p}) / 100' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* уменьшение на p% */
|
||
{
|
||
id: 'pct-decrease', topic: 'percents', order: 5, subject: 'algebra', grade: 6, kind: 'compute',
|
||
title: 'Уменьшение на p%',
|
||
pick: { abase: [1, 9], pidx: [1, 18] },
|
||
derive: { a: 'abase*100', p: 'pidx*5', val: 'abase*(100 - pidx*5)' },
|
||
lhs: 'x', rhs: '{a}*(100 - {p})/100', display: 'Число {a} уменьшили на {p}%. Какое число получилось?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Уменьшение на {p}% — это умножение на (100 − {p})/100.', tex: 'x = {a} * (100 - {p}) / 100' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* на сколько процентов изменилось */
|
||
{
|
||
id: 'pct-change', topic: 'percents', order: 6, subject: 'algebra', grade: 7, kind: 'compute',
|
||
title: 'На сколько процентов выросло',
|
||
pick: { abase: [2, 12], pidx: [1, 10] },
|
||
derive: { a: 'abase*20', p: 'pidx*5', b: 'abase*(100 + pidx*5)/5', val: 'pidx*5' },
|
||
lhs: 'x', rhs: '100*({b} - {a})/{a}', display: 'Цена выросла с {a} руб до {b} руб. На сколько процентов выросла цена?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Рост в рублях: {b} − {a}.', tex: '{b} - {a}' },
|
||
{ note: 'Какую долю это составляет от исходной цены — делим на {a} и умножаем на 100.', tex: 'x = 100 * ({b} - {a}) / {a}' },
|
||
{ note: 'Считаем (в процентах).', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* простые проценты (вклад) */
|
||
{
|
||
id: 'pct-simple-interest', topic: 'percents', order: 7, subject: 'algebra', grade: 8, kind: 'compute',
|
||
title: 'Простые проценты',
|
||
pick: { sbase: [1, 9], pidx: [1, 6], n: [1, 4] },
|
||
derive: { S: 'sbase*100', p: 'pidx*5', val: 'S*(100 + p*n)/100' },
|
||
lhs: 'x', rhs: '{S}*(100 + {p}*{n})/100', display: 'В банк положили {S} руб под {p}% годовых (простые проценты). Какая сумма будет на счёте через {n} г.?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'За {n} г. простыми процентами начислят {p}·{n}% от вклада.', tex: '{p} * {n}' },
|
||
{ note: 'Итог — вклад плюс проценты:', tex: 'x = {S} * (100 + {p} * {n}) / 100' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* сложные проценты (2 года) */
|
||
{
|
||
id: 'pct-compound-2y', topic: 'percents', order: 8, subject: 'algebra', grade: 9, kind: 'compute',
|
||
title: 'Сложные проценты (2 года)',
|
||
pick: { sbase: [1, 3], pidx: [1, 4] },
|
||
derive: { S: 'sbase*10000', p: 'pidx*10', val: 'S*(100 + p)^2/10000' },
|
||
lhs: 'x', rhs: '{S}*(100 + {p})^2/10000', display: 'Вклад {S} руб под {p}% годовых с ежегодной капитализацией. Какая сумма будет через 2 года?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Капитализация: каждый год сумма умножается на (100+{p})/100. За 2 года — дважды.', tex: 'x = {S} * (100 + {p}) / 100 * (100 + {p}) / 100' },
|
||
{ note: 'Это умножение на квадрат множителя:', tex: 'x = {S} * (100 + {p})^2 / 10000' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* найти исходное до повышения */
|
||
{
|
||
id: 'pct-restore-before', topic: 'percents', order: 9, subject: 'algebra', grade: 8, kind: 'compute',
|
||
title: 'Цена до повышения',
|
||
pick: { abase: [1, 9], pidx: [1, 8] },
|
||
derive: { a: 'abase*100', p: 'pidx*5', b: 'abase*(100 + pidx*5)', val: 'abase*100' },
|
||
lhs: 'x', rhs: '{b}*100/(100 + {p})', display: 'После повышения на {p}% цена стала {b} руб. Какой была цена до повышения (в рублях)?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Новая цена — это (100 + {p})% от старой, то есть старая × (100 + {p})/100 = {b}.', tex: '{b} = x * (100 + {p}) / 100' },
|
||
{ note: 'Выражаем старую цену:', tex: 'x = {b} * 100 / (100 + {p})' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* ── Текстовые: движение, работа, смеси, прибыль ── */
|
||
|
||
/* встречное движение */
|
||
{
|
||
id: 'app-meet', topic: 'applied', order: 6, subject: 'algebra', grade: 7, kind: 'compute',
|
||
title: 'Встречное движение',
|
||
pick: { u: [20, 70], v: [20, 70], t: [2, 6] },
|
||
derive: { S: '(u + v)*t', val: 't' },
|
||
lhs: 'x', rhs: '{S}/({u}+{v})', display: 'Из двух городов навстречу выехали машины со скоростями {u} и {v} км/ч. Расстояние между городами {S} км. Через сколько часов они встретятся?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'При встречном движении скорости складываются — машины сближаются на ({u}+{v}) км/ч.', tex: '{u} + {v}' },
|
||
{ note: 'Время до встречи — расстояние ÷ скорость сближения.', tex: 'x = {S} / ({u} + {v})' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* движение вдогонку */
|
||
{
|
||
id: 'app-overtake', topic: 'applied', order: 7, subject: 'algebra', grade: 8, kind: 'compute',
|
||
title: 'Движение вдогонку',
|
||
pick: { u: [10, 40], g: [5, 30], t: [2, 6] },
|
||
derive: { v: 'u + g', d: 'g*t', val: 't' },
|
||
lhs: 'x', rhs: '{d}/({v}-{u})', display: 'Велосипедист едет со скоростью {u} км/ч, мотоциклист — со скоростью {v} км/ч, отставая на {d} км. Через сколько часов мотоциклист догонит велосипедиста?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'При движении вдогонку скорость сближения — разность скоростей: {v} − {u}.', tex: '{v} - {u}' },
|
||
{ note: 'Время — отставание ÷ скорость сближения.', tex: 'x = {d} / ({v} - {u})' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* движение по реке (против течения) */
|
||
{
|
||
id: 'app-upstream', topic: 'applied', order: 8, subject: 'algebra', grade: 7, kind: 'compute',
|
||
title: 'Скорость против течения',
|
||
pick: { v: [8, 25], c: [1, 6] }, constraint: 'c < v',
|
||
derive: { val: 'v - c' },
|
||
lhs: 'x', rhs: '{v}-{c}', display: 'Собственная скорость лодки {v} км/ч, скорость течения {c} км/ч. С какой скоростью лодка идёт против течения (км/ч)?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Против течения скорость лодки уменьшается на скорость течения.', tex: 'x = {v} - {c}' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* совместная работа */
|
||
{
|
||
id: 'app-work-joint', topic: 'applied', order: 9, subject: 'algebra', grade: 8, kind: 'compute',
|
||
title: 'Совместная работа',
|
||
pick: { t: [2, 6], a: [3, 14] }, constraint: 'a > t',
|
||
derive: { b: 'a*t/(a - t)', val: 't' },
|
||
require: 'mod(a*t, a - t) == 0 && b >= 2 && b <= 60',
|
||
lhs: 'x', rhs: '{a}*{b}/({a}+{b})', display: 'Первый рабочий выполнит работу за {a} ч, второй — за {b} ч. За сколько часов они выполнят её, работая вместе?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'За час первый делает 1/{a} работы, второй 1/{b}. Вместе их производительности складываются.', tex: '1/{a} + 1/{b}' },
|
||
{ note: 'Время совместной работы — это произведение, делённое на сумму:', tex: 'x = {a} * {b} / ({a} + {b})' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* смешивание двух растворов */
|
||
{
|
||
id: 'app-mix-blend', topic: 'applied', order: 10, subject: 'algebra', grade: 9, kind: 'compute',
|
||
title: 'Концентрация смеси',
|
||
pick: { m1: [1, 6], m2: [1, 6], p1: [10, 40], p2: [50, 90] },
|
||
derive: { val: '(m1*p1 + m2*p2)/(m1 + m2)' },
|
||
require: 'mod(m1*p1 + m2*p2, m1 + m2) == 0',
|
||
lhs: 'x', rhs: '({m1}*{p1} + {m2}*{p2})/({m1}+{m2})', display: 'Смешали {m1} кг раствора {p1}% и {m2} кг раствора {p2}%. Какова концентрация (в процентах) полученной смеси?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Вещества в первом растворе: {m1}·{p1}/100, во втором: {m2}·{p2}/100.', tex: '{m1} * {p1} / 100 + {m2} * {p2} / 100' },
|
||
{ note: 'Концентрация смеси — всё вещество ÷ общую массу, в процентах:', tex: 'x = ({m1} * {p1} + {m2} * {p2}) / ({m1} + {m2})' },
|
||
{ note: 'Считаем.', tex: 'x = {ans}' }
|
||
]
|
||
},
|
||
|
||
/* прибыль в процентах */
|
||
{
|
||
id: 'app-profit-pct', topic: 'applied', order: 11, subject: 'algebra', grade: 8, kind: 'compute',
|
||
title: 'Прибыль в процентах',
|
||
pick: { cbase: [1, 9], pidx: [1, 10] },
|
||
derive: { c: 'cbase*100', p: 'pidx*5', s: 'cbase*(100 + pidx*5)', val: 'pidx*5' },
|
||
lhs: 'x', rhs: '100*({s} - {c})/{c}', display: 'Товар купили за {c} руб, а продали за {s} руб. Сколько процентов прибыли получили?',
|
||
answerVar: 'x', answer: 'val', integerAnswer: true,
|
||
solution: [
|
||
{ note: 'Прибыль в рублях: {s} − {c}.', tex: '{s} - {c}' },
|
||
{ note: 'Сколько это процентов от закупочной цены — делим на {c} и умножаем на 100.', tex: 'x = 100 * ({s} - {c}) / {c}' },
|
||
{ 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,
|
||
// Геометрия — Окружность
|
||
'circ-length': 1, 'circ-diam': 1, 'circ-area': 2, 'circ-arc': 3,
|
||
// V4.1 — Линейные: новые формы
|
||
'lin-both-frac': 2, 'lin-x-denom': 3, 'lin-k-over-x': 2, 'lin-abs': 3,
|
||
'lin-frac-eq-frac': 3, 'lin-nested-paren': 3, 'lin-literal': 3,
|
||
'ineq-both-sides': 2, 'ineq-both-flip': 3, 'ineq-paren': 2, 'ineq-count-int': 2,
|
||
'sys-sum-diff': 1, 'sys-subst': 2, 'sys-word': 2, 'sys-3x3': 3,
|
||
// V4.1 — Пропорции/Проценты/Текстовые
|
||
'prop-direct-word': 1, 'prop-inverse-word': 2, 'prop-scale-map': 2, 'prop-compound': 3, 'prop-share-ratio': 2,
|
||
'pct-increase': 2, 'pct-decrease': 2, 'pct-change': 3, 'pct-simple-interest': 2, 'pct-compound-2y': 3, 'pct-restore-before': 3,
|
||
'app-meet': 2, 'app-overtake': 3, 'app-upstream': 2, 'app-work-joint': 3, 'app-mix-blend': 3, 'app-profit-pct': 3,
|
||
// НОД/НОК / Дроби / Десятичные / Отрицательные
|
||
'gcd-pair': 1, 'lcm-pair': 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);
|