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:
Maxim Dolgolyov
2026-06-25 17:39:21 +03:00
parent a7d20a0c90
commit 664751e273
2 changed files with 44 additions and 13 deletions
+35 -12
View File
@@ -835,34 +835,57 @@
},
/* ═══ Тема: НОД и НОК (5–6 класс) ═══
Числа строим как g·m и g·k (общий множитель g) → НОД ≥ g, не тривиален.
gcd/lcm — функции SimExpr (алгоритм Евклида), считаются и проверяются движком. */
Оба числа строим из ДВУХ простых множителей 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], k: [2, 8] }, constraint: 'm != k',
derive: { a: 'g*m', b: 'g*k', val: 'gcd(a, b)' },
pick: { ip: [0, 3], iq: [0, 3], e1: [1, 2], e2: [1, 2], f1: [1, 2], f2: [1, 2] },
constraint: 'ip < iq',
derive: {
p: '(ip==0)?2:((ip==1)?3:((ip==2)?5:7))',
q: '(iq==0)?2:((iq==1)?3:((iq==2)?5:7))',
a: 'p^e1 * q^f1', b: 'p^e2 * q^f2',
me: 'min(e1, e2)', mf: 'min(f1, f2)', val: 'gcd(a, b)'
},
require: 'a != b && a <= 400 && b <= 400',
lhs: 'x', rhs: 'gcd({a}, {b})', display: 'Найдите наибольший общий делитель (НОД) чисел {a} и {b}.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'Разложите числа на простые множители; НОД — произведение общих множителей в наименьших степенях (или алгоритм Евклида).', tex: '' },
{ note: 'Получаем:', tex: 'x = {ans}' }
{ note: 'Разложим {a} на простые множители:', tex: '{a} = {p}^{e1} * {q}^{f1}' },
{ note: 'Разложим {b} на простые множители:', tex: '{b} = {p}^{e2} * {q}^{f2}' },
{ note: 'НОД — произведение ОБЩИХ простых множителей в НАИМЕНЬШИХ степенях:', tex: 'x = {p}^{me} * {q}^{mf}' },
{ note: 'Перемножаем:', tex: 'x = {ans}' }
]
},
/* наименьшее общее кратное */
/* наименьшее общее кратное — через разложение на простые множители */
{
id: 'lcm-pair', topic: 'gcd-lcm', order: 2, subject: 'algebra', grade: 6, kind: 'compute',
title: 'НОК двух чисел',
pick: { g: [2, 6], m: [2, 7], k: [2, 7] }, constraint: 'm != k',
derive: { a: 'g*m', b: 'g*k', val: 'lcm(a, b)' },
pick: { ip: [0, 3], iq: [0, 3], e1: [1, 2], e2: [1, 2], f1: [1, 2], f2: [1, 2] },
constraint: 'ip < iq',
derive: {
p: '(ip==0)?2:((ip==1)?3:((ip==2)?5:7))',
q: '(iq==0)?2:((iq==1)?3:((iq==2)?5:7))',
a: 'p^e1 * q^f1', b: 'p^e2 * q^f2',
Me: 'max(e1, e2)', Mf: 'max(f1, f2)', val: 'lcm(a, b)'
},
require: 'a != b && a <= 400 && b <= 400',
lhs: 'x', rhs: 'lcm({a}, {b})', display: 'Найдите наименьшее общее кратное (НОК) чисел {a} и {b}.',
answerVar: 'x', answer: 'val', integerAnswer: true,
solution: [
{ note: 'НОК = произведение чисел, делённое на их НОД: НОК(a, b) = a·b ÷ НОД(a, b).', tex: '' },
{ note: 'Получаем:', tex: 'x = {ans}' }
{ note: 'Разложим {a} на простые множители:', tex: '{a} = {p}^{e1} * {q}^{f1}' },
{ note: 'Разложим {b} на простые множители:', tex: '{b} = {p}^{e2} * {q}^{f2}' },
{ note: 'НОК — произведение ВСЕХ простых множителей в НАИБОЛЬШИХ степенях:', tex: 'x = {p}^{Me} * {q}^{Mf}' },
{ note: 'Перемножаем:', tex: 'x = {ans}' }
]
},