feat(trainer): красивое решение НОД/НОК — через разложение на простые множители
- НОД/НОК переписаны: число строится из двух простых p<q (из {2,3,5,7}) со степенями 1..2 (a=p^e1·q^f1) → разложение известно из параметров. Решение показывает СТАНДАРТНЫЙ школьный метод: разложить оба числа, НОД = общие множители в наименьших степенях, НОК = все в наибольших. Пример: 225=3²·5², 45=3²·5 → НОД=3²·5=45
- выбор простого — тернарником в derive (ip/iq, НЕ pi — pi это π в SimExpr!)
- exprToLatex: x^1→x, x^0→1 (чтобы 7^1 печаталось как 7) + ставит · между числовыми множителями (2·7², а не слипшееся «27²»); алгебраическое неявное умножение (2x, 3(x+1)) сохранено
- gcd/lcm дают эталон для проверки, min/max — степени для шагов
- смоук движка 1154/1154, страница 40/40; эмодзи 0
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -160,6 +160,11 @@
|
||||
var s = _latex(node);
|
||||
return _prec(node) < minPrec ? '\\left(' + s + '\\right)' : s;
|
||||
}
|
||||
// «числовой множитель»: число, константа или степень с числовым основанием (2, 7^2).
|
||||
// Между двумя такими ставим ·, иначе адъяцентность «2·7²» прочитается как «27²».
|
||||
function _isNumFactor(n) {
|
||||
return n.k === 'num' || n.k === 'const' || (n.k === 'bin' && n.op === '^' && _isNumFactor(n.a));
|
||||
}
|
||||
// Операнд умножения: отрицательное/унарное/сумму берём в скобки, иначе
|
||||
// соседство схлопнет смысл (7*(-5) -> «7-5», 6*(x+1) -> «6x+1»).
|
||||
function _mulOperand(node) {
|
||||
@@ -197,6 +202,8 @@
|
||||
if (op === '/') return '\\frac{' + _latex(node.a) + '}{' + _latex(node.b) + '}';
|
||||
if (op === '^') {
|
||||
var base = _prec(node.a) < 5 ? '\\left(' + _latex(node.a) + '\\right)' : _latex(node.a);
|
||||
if (node.b.k === 'num' && node.b.v === 1) return base; // x^1 -> x
|
||||
if (node.b.k === 'num' && node.b.v === 0) return '1'; // x^0 -> 1
|
||||
return base + '^{' + _latex(node.b) + '}';
|
||||
}
|
||||
if (op === '*') {
|
||||
@@ -206,7 +213,8 @@
|
||||
if (node.b.k === 'num' && Math.abs(node.b.v) === 1 && node.a.k !== 'num')
|
||||
return (node.b.v < 0 ? '-' : '') + _mulOperand(node.a);
|
||||
if (_isNeg(node.a)) return '-' + _latex({ k: 'bin', op: '*', a: _negate(node.a), b: node.b }); // -5*x -> «-5x»
|
||||
var sep = (node.b.k === 'num' && node.b.v >= 0) ? ' \\cdot ' : ''; // знак · между числами; иначе соседство
|
||||
// · между числами и числовыми множителями (2·3, 2·7²); иначе соседство (2x, 3(x+1))
|
||||
var sep = ((node.b.k === 'num' && node.b.v >= 0) || (_isNumFactor(node.a) && _isNumFactor(node.b))) ? ' \\cdot ' : '';
|
||||
return _mulOperand(node.a) + sep + _mulOperand(node.b);
|
||||
}
|
||||
if (op === '%') return _wrapL(node.a, 2) + ' \\bmod ' + _wrapL(node.b, 3);
|
||||
|
||||
Reference in New Issue
Block a user