c370eaa803
- движок _trainer_engine.js: instantiate/generateBatch/verifyRoot/checkStudentAnswer/exprToLatex - 5 генераторов уравнений 7 класса (generators.js), приём «корень-вперёд» → целые ответы - страница /trainer: KaTeX-рендер, чипы-темы, мгновенная проверка, подсказка/решение, авто-выбор навыка - прогресс practice_progress (мигр.081) + /api/practice/progress|attempt + LS.practiceProgressList/Submit - фича-флаг trainer: тумблер в админке (Модули), requireFeature, FEATURE_HREFS (скрытие сайдбара+редирект), MODULE_CATALOG - fix: подключён Lucide CDN на странице (иначе иконки сайдбара пустые) - тесты practice.test.js (10/10); план развития plans/ai-trainer/PLAN.md Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
130 lines
5.7 KiB
JavaScript
130 lines
5.7 KiB
JavaScript
'use strict';
|
|
/* ════════════════════════════════════════════════════════════════════════
|
|
Генераторы уравнений — 7 класс (прототип). Это ДАННЫЕ, не код.
|
|
|
|
Приём «корень-вперёд»: выбираем целый корень (или множитель) и коэффициенты,
|
|
затем ВЫВОДИМ свободный член так, чтобы ответ гарантированно был целым, а
|
|
уравнение — решаемым. Поэтому самопроверка движка (verifyRoot) всегда
|
|
проходит. Шаг решения — { note(текст), tex(формула) }; tex рендерится в KaTeX
|
|
через TrainerEngine.exprToLatex (одно равенство на шаг, без цепочек a=b=c).
|
|
|
|
Прогрессия 7 класса: простое линейное → скобки → переменная в обеих частях →
|
|
уравнение с дробью в знаменателе → дробный коэффициент. Дальше (Уровень 1):
|
|
текстовые задачи через LLM с той же подстановочной верификацией.
|
|
════════════════════════════════════════════════════════════════════════ */
|
|
(function (global) {
|
|
|
|
var GENERATORS = [
|
|
|
|
/* 1. ax + b = c */
|
|
{
|
|
id: 'lin-basic',
|
|
skill: 'linear-basic',
|
|
title: 'Линейное: ax + b = c',
|
|
grade: 7,
|
|
pick: { a: [2, 9], b: [1, 20], root: [-9, 9] },
|
|
require: 'root != 0',
|
|
derive: { c: 'a*root + b', cmb: 'a*root' }, // cmb = c - b
|
|
lhs: '{a}*x + {b}', rhs: '{c}',
|
|
display: '{a}x + {b} = {c}',
|
|
answerVar: 'x', answer: 'root', integerAnswer: true,
|
|
solution: [
|
|
{ note: 'Переносим число вправо:', tex: '{a}x = {cmb}' },
|
|
{ note: 'Делим обе части на {a}:', tex: 'x = {cmb} / {a}' },
|
|
{ note: 'Ответ:', tex: 'x = {ans}' }
|
|
]
|
|
},
|
|
|
|
/* 2. a(x + b) = c */
|
|
{
|
|
id: 'lin-paren',
|
|
skill: 'linear-parentheses',
|
|
title: 'Со скобками: a(x + b) = c',
|
|
grade: 7,
|
|
pick: { a: [2, 8], b: [1, 12], root: [-9, 9] },
|
|
require: 'root != 0',
|
|
derive: { c: 'a*(root + b)', ca: 'root + b' }, // ca = c / a
|
|
lhs: '{a}*(x + {b})', rhs: '{c}',
|
|
display: '{a}(x + {b}) = {c}',
|
|
answerVar: 'x', answer: 'root', integerAnswer: true,
|
|
solution: [
|
|
{ note: 'Делим обе части на {a}:', tex: 'x + {b} = {ca}' },
|
|
{ note: 'Переносим {b} влево:', tex: 'x = {ca} - {b}' },
|
|
{ note: 'Ответ:', tex: 'x = {ans}' }
|
|
]
|
|
},
|
|
|
|
/* 3. ax + b = cx + d */
|
|
{
|
|
id: 'lin-both-sides',
|
|
skill: 'linear-both-sides',
|
|
title: 'Переменная с двух сторон: ax + b = cx + d',
|
|
grade: 7,
|
|
pick: { a: [3, 9], c: [1, 8], b: [1, 20], root: [-9, 9] },
|
|
constraint: 'c < a', // гарантируем a - c > 0
|
|
require: 'root != 0',
|
|
derive: { d: '(a - c)*root + b', amc: 'a - c', dmb: '(a - c)*root' }, // dmb = d - b
|
|
lhs: '{a}*x + {b}', rhs: '{c}*x + {d}',
|
|
display: '{a}x + {b} = {c}x + {d}',
|
|
answerVar: 'x', answer: 'root', integerAnswer: true,
|
|
solution: [
|
|
{ note: 'Собираем x слева, числа справа:', tex: '({a} - {c})x = {d} - {b}' },
|
|
{ note: 'Приводим подобные:', tex: '{amc}x = {dmb}' },
|
|
{ note: 'Делим на {amc}:', tex: 'x = {dmb} / {amc}' },
|
|
{ note: 'Ответ:', tex: 'x = {ans}' }
|
|
]
|
|
},
|
|
|
|
/* 4. x/a + b = c (дробь в знаменателе) */
|
|
{
|
|
id: 'lin-frac-denom',
|
|
skill: 'linear-fraction-denom',
|
|
title: 'Дробь: x/a + b = c',
|
|
grade: 7,
|
|
pick: { a: [2, 6], k: [-6, 6], b: [1, 12] },
|
|
require: 'k != 0',
|
|
derive: { root: 'a*k', c: 'k + b', cmb: 'k' }, // root = a·k, cmb = c - b = k
|
|
lhs: 'x/{a} + {b}', rhs: '{c}',
|
|
display: 'x/{a} + {b} = {c}',
|
|
answerVar: 'x', answer: 'root', integerAnswer: true,
|
|
solution: [
|
|
{ note: 'Вычитаем {b}:', tex: 'x/{a} = {cmb}' },
|
|
{ note: 'Умножаем обе части на {a}:', tex: 'x = {cmb} * {a}' },
|
|
{ note: 'Ответ:', tex: 'x = {ans}' }
|
|
]
|
|
},
|
|
|
|
/* 5. (a·x)/b = c (дробный коэффициент) */
|
|
{
|
|
id: 'lin-coef-frac',
|
|
skill: 'linear-coef-frac',
|
|
title: 'Дробный коэффициент: ax/b = c',
|
|
grade: 7,
|
|
pick: { a: [2, 5], b: [2, 5], m: [-5, 5] },
|
|
require: 'm != 0',
|
|
derive: { root: 'b*m', c: 'a*m', cb: 'a*m*b' }, // root = b·m, c = a·m, cb = c·b
|
|
lhs: '{a}*x/{b}', rhs: '{c}',
|
|
display: '{a}x/{b} = {c}',
|
|
answerVar: 'x', answer: 'root', integerAnswer: true,
|
|
solution: [
|
|
{ note: 'Умножаем обе части на {b}:', tex: '{a}x = {cb}' },
|
|
{ note: 'Делим на {a}:', tex: 'x = {cb} / {a}' },
|
|
{ note: 'Ответ:', tex: 'x = {ans}' }
|
|
]
|
|
}
|
|
|
|
];
|
|
|
|
function get(id) {
|
|
for (var i = 0; i < GENERATORS.length; i++) if (GENERATORS[i].id === id) return GENERATORS[i];
|
|
return null;
|
|
}
|
|
|
|
global.TrainerGenerators = {
|
|
list: function () { return GENERATORS.slice(); },
|
|
get: get,
|
|
GENERATORS: GENERATORS
|
|
};
|
|
|
|
})(typeof window !== 'undefined' ? window : globalThis);
|