diff --git a/frontend/textbooks/algebra_8_ch2.html b/frontend/textbooks/algebra_8_ch2.html index 7113dae..0fbf1f0 100644 --- a/frontend/textbooks/algebra_8_ch2.html +++ b/frontend/textbooks/algebra_8_ch2.html @@ -1037,12 +1037,14 @@ function buildP10(){
`); /* INT 2 — Шаговый разлагатель */ - html += widget('Пошаговый разлагатель','INTERACT 2','Введите $a$, $b$, $c$ — система разложит трёхчлен по шагам.',` + html += widget('Пошаговый разлагатель','INTERACT 2','Введите $a$, $b$, $c$ и нажимайте «Дальше» — каждый шаг отдельно.',`
- + + +
`); @@ -1121,24 +1123,51 @@ function buildP10(){ refresh(); })(); - /* INIT 2 */ + /* INIT 2 — пошаговый */ (function(){ - document.getElementById('p10s-go').addEventListener('click', ()=>{ - const a = +document.getElementById('p10s-a').value; - const b = +document.getElementById('p10s-b').value; - const c = +document.getElementById('p10s-c').value; - const stage = document.getElementById('p10s-stage'); - if(!a){ stage.innerHTML = '

$a$ не может быть нулём.

'; return; } + const stage = document.getElementById('p10s-stage'); + const goBtn = document.getElementById('p10s-go'); + const nextBtn = document.getElementById('p10s-next'); + const resetBtn = document.getElementById('p10s-reset'); + let steps = [], idx = 0, awarded = false; + function build(a, b, c){ const D = b*b - 4*a*c; - let html = '

Шаг 1: $D = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$

'; - if(D < 0){ html += '

Шаг 2: $D < 0$ → трёхчлен не раскладывается на множители с действительными коэффициентами.

'; } - else { + const arr = []; + arr.push('Шаг 1. Исходный трёхчлен: $' + a + 'x^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + '$'); + arr.push('Шаг 2. $D = b^2 - 4ac = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$'); + if(D < 0){ + arr.push('Шаг 3. $D < 0$ — на множители первой степени с действительными коэффициентами не раскладывается.'); + } else { const x1 = (-b - Math.sqrt(D))/(2*a), x2 = (-b + Math.sqrt(D))/(2*a); - html += '

Шаг 2: $x_1 = ' + fmt(x1) + ',\\ x_2 = ' + fmt(x2) + '$

'; - html += '

Шаг 3: $' + a + 'x^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = ' + (a === 1 ? '' : a) + '(x ' + (x1 >= 0 ? '- ' + fmt(x1) : '+ ' + fmt(-x1)) + ')(x ' + (x2 >= 0 ? '- ' + fmt(x2) : '+ ' + fmt(-x2)) + ')$

'; + arr.push('Шаг 3. Корни: $x_1 = ' + fmt(x1) + ',\\ x_2 = ' + fmt(x2) + '$'); + arr.push('Шаг 4. Подставляем в формулу $a(x-x_1)(x-x_2)$:'); + arr.push('Ответ: $' + (a === 1 ? '' : a) + '(x ' + (x1 >= 0 ? '- ' + fmt(x1) : '+ ' + fmt(-x1)) + ')(x ' + (x2 >= 0 ? '- ' + fmt(x2) : '+ ' + fmt(-x2)) + ')$'); } - stage.innerHTML = html; renderMath(stage); - achievement('p10_steps'); bumpProgress('p10', 14); + return arr; + } + function render(){ + stage.innerHTML = steps.slice(0, idx + 1) + .map(s => `
${s}
`) + .join(''); + renderMath(stage); + if(idx >= steps.length - 1){ + nextBtn.disabled = true; nextBtn.textContent = 'Готово'; + if(!awarded){ awarded = true; achievement('p10_steps'); bumpProgress('p10', 14); confetti(); } + } else { + nextBtn.disabled = false; nextBtn.textContent = 'Дальше (' + (idx + 1) + '/' + steps.length + ')'; + } + } + goBtn.addEventListener('click', ()=>{ + const a = +document.getElementById('p10s-a').value, b = +document.getElementById('p10s-b').value, c = +document.getElementById('p10s-c').value; + if(!a){ stage.innerHTML = '

$a$ не может быть нулём.

'; renderMath(stage); return; } + steps = build(a, b, c); idx = 0; awarded = false; + goBtn.style.display = 'none'; nextBtn.style.display = ''; resetBtn.style.display = ''; + render(); + }); + nextBtn.addEventListener('click', ()=>{ if(idx < steps.length - 1){ idx++; render(); } }); + resetBtn.addEventListener('click', ()=>{ + idx = 0; steps = []; awarded = false; stage.innerHTML = ''; + goBtn.style.display = ''; nextBtn.style.display = 'none'; resetBtn.style.display = 'none'; }); })(); @@ -1568,12 +1597,14 @@ function buildP12(){

3) $\\dfrac{x}{x-2} - \\dfrac{2}{x+2} = 1$. ОДЗ: $x \\neq \\pm 2$. Умножим на $(x-2)(x+2)$: $x(x+2) - 2(x-2) = (x-2)(x+2) \\Rightarrow x^2 + 2x - 2x + 4 = x^2 - 4 \\Rightarrow 4 = -4$ — противоречие, корней нет.

`); /* INT 1 — Биквадратное пошагово */ - html += widget('Решатель биквадратного','INTERACT 1','Введите $a$, $b$, $c$ — система применит замену $t=x^2$ и доведёт до конца.',` + html += widget('Решатель биквадратного','INTERACT 1','Введите $a$, $b$, $c$ и нажимайте «Дальше» — шаги замены и решения.',`
- + + +
`); @@ -1626,33 +1657,59 @@ function buildP12(){ box.innerHTML = html; if(window.renderMathInElement) setTimeout(()=>renderMath(box), 0); - /* INIT 1 — Биквадратное */ + /* INIT 1 — Биквадратное пошагово */ (function(){ - document.getElementById('p12b-go').addEventListener('click', ()=>{ - const a = +document.getElementById('p12b-a').value; - const b = +document.getElementById('p12b-b').value; - const c = +document.getElementById('p12b-c').value; - const out = document.getElementById('p12b-out'); - if(!a){ out.innerHTML = '$a \\neq 0$'; renderMath(out); return; } - let html = '
Дано: $' + a + 'x^4 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x^2 ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$
'; - html += '
Замена $t = x^2,\\ t \\geq 0$: $' + a + 't^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 't ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$
'; + const out = document.getElementById('p12b-out'); + const goBtn = document.getElementById('p12b-go'); + const nextBtn = document.getElementById('p12b-next'); + const resetBtn = document.getElementById('p12b-reset'); + let steps = [], idx = 0, awarded = false; + function build(a, b, c){ + const arr = []; + arr.push('Дано: $' + a + 'x^4 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x^2 ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$'); + arr.push('Замена. Пусть $t = x^2,\\ t \\geq 0$. Получаем $' + a + 't^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 't ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0$'); const D = b*b - 4*a*c; - html += '
D = ' + (b*b) + ' − ' + (4*a*c) + ' = ' + D + '
'; - if(D < 0){ html += '
$D < 0$ → нет $t$, значит нет $x$.
'; } - else { + arr.push('Дискриминант. $D = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$'); + if(D < 0){ + arr.push('Анализ. $D < 0 \\Rightarrow$ нет $t$, значит нет $x$.'); + arr.push('Ответ: корней нет.'); + } else { const t1 = (-b - Math.sqrt(D))/(2*a), t2 = (-b + Math.sqrt(D))/(2*a); - html += '
$t_1 = ' + fmt(t1) + ',\\ t_2 = ' + fmt(t2) + '$
'; + arr.push('Корни вспомогательного. $t_1 = ' + fmt(t1) + ',\\ t_2 = ' + fmt(t2) + '$'); const roots = []; [t1, t2].forEach((t, k)=>{ - if(t > 0){ const r = Math.sqrt(t); roots.push(r, -r); html += '
$t_' + (k+1) + ' = ' + fmt(t) + ' > 0 \\Rightarrow x = \\pm' + fmt(r) + '$
'; } - else if(t === 0){ roots.push(0); html += '
$t_' + (k+1) + ' = 0 \\Rightarrow x = 0$
'; } - else html += '
$t_' + (k+1) + ' = ' + fmt(t) + ' < 0$ — не подходит
'; + if(t > 0){ const r = Math.sqrt(t); roots.push(r, -r); arr.push('Возврат. $t_' + (k+1) + ' = ' + fmt(t) + ' > 0 \\Rightarrow x = \\pm\\sqrt{' + fmt(t) + '} = \\pm' + fmt(r) + '$'); } + else if(t === 0){ roots.push(0); arr.push('Возврат. $t_' + (k+1) + ' = 0 \\Rightarrow x = 0$'); } + else arr.push('Возврат. $t_' + (k+1) + ' = ' + fmt(t) + ' < 0$ — не подходит, ведь $t \\geq 0$.'); }); const u = [...new Set(roots)].sort((a,b)=>a-b); - html += '
Ответ: ' + (u.length ? '$\\{' + u.map(fmt).join(';\\ ') + '\\}$' : 'корней нет') + '
'; + arr.push('Ответ: ' + (u.length ? '$\\{' + u.map(fmt).join(';\\ ') + '\\}$' : 'корней нет')); } - out.innerHTML = html; renderMath(out); - achievement('p12_bi'); bumpProgress('p12', 14); + return arr; + } + function render(){ + out.innerHTML = steps.slice(0, idx + 1) + .map(s => `
${s}
`) + .join(''); + renderMath(out); + if(idx >= steps.length - 1){ + nextBtn.disabled = true; nextBtn.textContent = 'Готово'; + if(!awarded){ awarded = true; achievement('p12_bi'); bumpProgress('p12', 14); confetti(); } + } else { + nextBtn.disabled = false; nextBtn.textContent = 'Дальше (' + (idx + 1) + '/' + steps.length + ')'; + } + } + goBtn.addEventListener('click', ()=>{ + const a = +document.getElementById('p12b-a').value, b = +document.getElementById('p12b-b').value, c = +document.getElementById('p12b-c').value; + if(!a){ out.innerHTML = '$a \\neq 0$'; renderMath(out); return; } + steps = build(a, b, c); idx = 0; awarded = false; + goBtn.style.display = 'none'; nextBtn.style.display = ''; resetBtn.style.display = ''; + render(); + }); + nextBtn.addEventListener('click', ()=>{ if(idx < steps.length - 1){ idx++; render(); } }); + resetBtn.addEventListener('click', ()=>{ + idx = 0; steps = []; awarded = false; out.innerHTML = ''; + goBtn.style.display = ''; nextBtn.style.display = 'none'; resetBtn.style.display = 'none'; }); })(); @@ -2585,12 +2642,14 @@ function buildP8(){ `); /* INTERACTIVE 5: пошаговый */ - html += widget('Пошаговый решатель','INTERACT 5','Введите $a$, $b$, $c$ — система разложит решение по шагам.',` + html += widget('Пошаговый решатель','INTERACT 5','Введите $a$, $b$, $c$ и нажимайте «Дальше» — каждый шаг появляется отдельно.',`
- + + +
`); @@ -2755,8 +2814,9 @@ function buildP8(){ const txt = 'x^2 ' + (b >= 0 ? '+ ' + b : '- ' + Math.abs(b)) + 'x ' + (c >= 0 ? '+ ' + c : '- ' + Math.abs(c)) + ' = 0'; document.getElementById('p8t-task').innerHTML = '$' + txt + '$'; document.getElementById('p8t-i').textContent = i; - document.getElementById('p8t-d-hint').textContent = 'Подскажу: $D = b^2 - 4ac$'; + document.getElementById('p8t-d-hint').innerHTML = 'Подскажу: $D = b^2 - 4ac$'; renderMath(document.getElementById('p8t-task')); + renderMath(document.getElementById('p8t-d-hint')); document.getElementById('p8t-fb').style.display = 'none'; } function answer(n){ @@ -2775,25 +2835,66 @@ function buildP8(){ document.getElementById('p8t-0').addEventListener('click', ()=>answer(0)); })(); - /* INIT INTERACTIVE 5 */ + /* INIT INTERACTIVE 5 — пошаговый по одному шагу */ (function initSteps(){ - document.getElementById('p8s-go').addEventListener('click', ()=>{ + const stage = document.getElementById('p8s-stage'); + const goBtn = document.getElementById('p8s-go'); + const nextBtn = document.getElementById('p8s-next'); + const resetBtn = document.getElementById('p8s-reset'); + let steps = [], idx = 0, awarded = false; + function buildSteps(a, b, c){ + const D = b*b - 4*a*c; + const arr = []; + arr.push('Шаг 1. Выпишем коэффициенты: $a = ' + a + ',\\ b = ' + b + ',\\ c = ' + c + '$'); + arr.push('Шаг 2. $D = b^2 - 4ac = (' + b + ')^2 - 4 \\cdot (' + a + ') \\cdot (' + c + ') = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$'); + arr.push('Шаг 3. ' + (D > 0 ? '$D > 0 \\Rightarrow$ два корня' : D === 0 ? '$D = 0 \\Rightarrow$ один корень' : '$D < 0 \\Rightarrow$ корней нет')); + if(D >= 0){ + arr.push('Шаг 4. $\\sqrt{D} = \\sqrt{' + D + '} = ' + fmt(Math.sqrt(D)) + '$'); + if(D > 0){ + const r1 = (-b - Math.sqrt(D))/(2*a), r2 = (-b + Math.sqrt(D))/(2*a); + arr.push('Шаг 5. $x_{1,2} = \\dfrac{-b \\pm \\sqrt{D}}{2a} = \\dfrac{' + (-b) + ' \\pm ' + fmt(Math.sqrt(D)) + '}{' + (2*a) + '}$'); + arr.push('Шаг 6. $x_1 = ' + fmt(r1) + ',\\ x_2 = ' + fmt(r2) + '$'); + } else { + arr.push('Шаг 5. $x = \\dfrac{-b}{2a} = \\dfrac{' + (-b) + '}{' + (2*a) + '} = ' + fmt(-b/(2*a)) + '$'); + } + } + arr.push('Ответ: ' + (D > 0 ? 'два корня' : D === 0 ? 'один корень' : 'корней нет')); + return arr; + } + function render(){ + const html = steps.slice(0, idx + 1) + .map((s, k)=>`
${s}
`) + .join(''); + stage.innerHTML = html; + renderMath(stage); + if(idx >= steps.length - 1){ + nextBtn.disabled = true; + nextBtn.textContent = 'Готово'; + if(!awarded){ awarded = true; achievement('p8_steps'); bumpProgress('p8', 14); confetti(); } + } else { + nextBtn.disabled = false; + nextBtn.textContent = 'Дальше (' + (idx + 1) + '/' + steps.length + ')'; + } + } + goBtn.addEventListener('click', ()=>{ const a = +document.getElementById('p8s-a').value; const b = +document.getElementById('p8s-b').value; const c = +document.getElementById('p8s-c').value; - const stage = document.getElementById('p8s-stage'); - if(!a){ stage.innerHTML = '

$a$ не может быть нулём.

'; return; } - const D = b*b - 4*a*c; - let html = '

Шаг 1: $a = ' + a + ',\\ b = ' + b + ',\\ c = ' + c + '$

'; - html += '

Шаг 2: $D = b^2 - 4ac = ' + b + '^2 - 4 \\cdot ' + a + ' \\cdot ' + c + ' = ' + (b*b) + ' - ' + (4*a*c) + ' = ' + D + '$

'; - html += '

Шаг 3: ' + (D > 0 ? '$D > 0$ → два корня' : D === 0 ? '$D = 0$ → один корень' : '$D < 0$ → корней нет') + '

'; - if(D >= 0){ - html += '

Шаг 4: $\\sqrt{D} = ' + fmt(Math.sqrt(D)) + '$

'; - if(D > 0){ const r1 = (-b - Math.sqrt(D))/(2*a), r2 = (-b + Math.sqrt(D))/(2*a); html += '

Шаг 5: $x_1 = \\dfrac{' + (-b) + ' - ' + fmt(Math.sqrt(D)) + '}{' + (2*a) + '} = ' + fmt(r1) + ',\\ x_2 = ' + fmt(r2) + '$

'; } - else html += '

Шаг 5: $x = \\dfrac{' + (-b) + '}{' + (2*a) + '} = ' + fmt(-b/(2*a)) + '$

'; - } - stage.innerHTML = html; renderMath(stage); - achievement('p8_steps'); bumpProgress('p8', 12); + if(!a){ stage.innerHTML = '

$a$ не может быть нулём.

'; renderMath(stage); return; } + steps = buildSteps(a, b, c); + idx = 0; awarded = false; + goBtn.style.display = 'none'; + nextBtn.style.display = ''; resetBtn.style.display = ''; + nextBtn.disabled = false; + render(); + }); + nextBtn.addEventListener('click', ()=>{ + if(idx < steps.length - 1){ idx++; render(); } + }); + resetBtn.addEventListener('click', ()=>{ + idx = 0; steps = []; awarded = false; + stage.innerHTML = ''; + goBtn.style.display = ''; nextBtn.style.display = 'none'; resetBtn.style.display = 'none'; }); })();