feat(trainer): P1 — темы/навыки, +8 генераторов, подробные пошаговые решения
- таксономия тема→навык (topics/byTopic), метаданные topic/order/subject/grade - 13 генераторов в 3 темах: Уравнения (+a(x+b)=c(x+d), (ax+b)/c=d), Пропорции (3), Проценты (3) - проценты как compute-задачи: текстовый prompt + проверка подстановкой (latex уравнения скрыт) - подробные объяснения: каждый шаг расписан словами + шаг «Проверка» (подстановка корня) - UI: вкладки тем + чипы навыков, бейджи мастерства, авто-выбор первой неосвоенной темы/навыка - движок: exprToLatex чинит отрицательные множители (7·(−5)), поле kind, нумерованные шаги решения - смоуки 238/238 (движок) + 19/19 (страница); план: P1 отмечен DONE Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -134,6 +134,12 @@
|
||||
var s = _latex(node);
|
||||
return _prec(node) < minPrec ? '\\left(' + s + '\\right)' : s;
|
||||
}
|
||||
// Операнд умножения: отрицательное/унарное/сумму берём в скобки, иначе
|
||||
// соседство схлопнет смысл (7*(-5) -> «7-5», 6*(x+1) -> «6x+1»).
|
||||
function _mulOperand(node) {
|
||||
if (_isNeg(node) || _prec(node) < 2) return '\\left(' + _latex(node) + '\\right)';
|
||||
return _latex(node);
|
||||
}
|
||||
function _latex(node) {
|
||||
switch (node.k) {
|
||||
case 'num': return fmtNum(node.v);
|
||||
@@ -168,8 +174,8 @@
|
||||
return base + '^{' + _latex(node.b) + '}';
|
||||
}
|
||||
if (op === '*') {
|
||||
var sep = (node.b.k === 'num') ? ' \\cdot ' : ''; // ·число; иначе соседство (7x, 6(x+1))
|
||||
return _wrapL(node.a, 2) + sep + _wrapL(node.b, 2);
|
||||
var sep = (node.b.k === 'num' && node.b.v >= 0) ? ' \\cdot ' : ''; // знак · между числами; иначе соседство
|
||||
return _mulOperand(node.a) + sep + _mulOperand(node.b);
|
||||
}
|
||||
if (op === '%') return _wrapL(node.a, 2) + ' \\bmod ' + _wrapL(node.b, 3);
|
||||
// + или - (схлопываем a + (-b) -> a - b)
|
||||
@@ -233,12 +239,17 @@
|
||||
var lhsExpr = render(gen.lhs, env);
|
||||
var rhsExpr = render(gen.rhs, env);
|
||||
var sEnv = assign(env, { ans: answer });
|
||||
var ll = exprToLatex(lhsExpr), rl = exprToLatex(rhsExpr);
|
||||
// compute-задача (проценты): показываем текстовый prompt из display, а
|
||||
// уравнение lhs=rhs служит лишь для проверки → latex уравнения не строим.
|
||||
var isCompute = gen.kind === 'compute';
|
||||
var ll = isCompute ? null : exprToLatex(lhsExpr);
|
||||
var rl = isCompute ? null : exprToLatex(rhsExpr);
|
||||
|
||||
var problem = {
|
||||
genId: gen.id,
|
||||
skill: gen.skill,
|
||||
skill: gen.skill || gen.id, // ключ прогресса = id генератора, если skill не задан
|
||||
title: gen.title,
|
||||
kind: gen.kind || 'solve',
|
||||
lhsExpr: lhsExpr,
|
||||
rhsExpr: rhsExpr,
|
||||
display: prettyMath(render(gen.display || (gen.lhs + ' = ' + gen.rhs), env)),
|
||||
|
||||
Reference in New Issue
Block a user