diff --git a/frontend/textbooks/algebra_8_ch2.html b/frontend/textbooks/algebra_8_ch2.html index 7825be0..d8a17f8 100644 --- a/frontend/textbooks/algebra_8_ch2.html +++ b/frontend/textbooks/algebra_8_ch2.html @@ -391,6 +391,16 @@ const ACH_LABELS = { p10_train: 'Тренажёр разложения', p10_fraction: 'Сокращение дробей', p10_sort: 'Разложимо или нет', + p11_steps: 'Решил по 4 шагам', + p11_train: 'Тренажёр текстовых задач', + p11_move: 'Движение по реке', + p11_digit: 'Двузначное число', + p11_class: 'Классификатор задач', + p12_bi: 'Биквадратное решено', + p12_train: 'Тренажёр биквадратных', + p12_frac: 'Дробное → квадратное', + p12_subst: 'Замена переменной', + p12_odz: 'Посторонний корень', }; function loadProgress(){ @@ -528,8 +538,19 @@ const SIDEBARS = { ['Корни','через дискриминант или Виета'], ['Сокращение','через разложение числителя и знаменателя'], ]}, - p11:{ title:'§ 11 — скоро', rows:[['Текстовые задачи','будет в Wave 3']]}, - p12:{ title:'§ 12 — скоро', rows:[['Сводящиеся к квадратным','будет в Wave 3']]}, + p11:{ title:'Шпаргалка § 11', rows:[ + ['4 шага','анализ → модель → решение → проверка'], + ['Движение','$s = v t$; общее $\\dfrac{s_1}{v_1} + \\dfrac{s_2}{v_2}$'], + ['Работа','$A = p \\cdot t$; вместе: $p_1 + p_2 = \\dfrac{1}{t}$'], + ['Числа','$\\overline{ab} = 10a + b$'], + ]}, + p12:{ title:'Шпаргалка § 12', rows:[ + ['Биквадр','$ax^4+bx^2+c=0$ → $t=x^2$'], + ['Условие','$t \\geq 0$'], + ['$x = \\pm\\sqrt{t}$','для каждого $t \\geq 0$'], + ['Дробное','умножить на ОЗ, проверить ОДЗ'], + ['ОДЗ','знаменатель $\\neq 0$'], + ]}, final2:{ title:'Финал', rows:[['Итоги главы','будет в Wave 4']]}, }; function buildSidebar(id){ @@ -1216,8 +1237,527 @@ function buildP10(){ render(); })(); } -function buildP11stub(){ document.getElementById('p11-body').innerHTML = `

§ 11 — Текстовые задачи

Скоро в Wave 3.

${secNav('p10','p12')}`; } -function buildP12stub(){ document.getElementById('p12-body').innerHTML = `

§ 12 — Сводящиеся к квадратным

Скоро в Wave 3.

${secNav('p11','final2')}`; } +function buildP11stub(){ buildP11(); } +function buildP11(){ + const box = document.getElementById('p11-body'); + let html = ''; + + html += makeCard('repeat','Повторение',null,` + `); + + html += makeCard('theory','4 шага решения','11.1',` +
    +
  1. Анализ. Прочесть условие, выделить величины, связи, искомое.
  2. +
  3. Модель. Обозначить неизвестное буквой; выразить остальные величины через неё; составить уравнение.
  4. +
  5. Решение. Решить уравнение — обычно квадратное.
  6. +
  7. Анализ ответа. Проверить смысл (положительные ли значения, целые ли — если требуется), записать ответ.
  8. +
`); + + html += makeCard('example','Образец',null,` +

Задача. Произведение двух последовательных натуральных чисел равно 132. Найдите эти числа.

+

Решение. Пусть меньшее $= x$. Тогда $x(x+1) = 132 \\Rightarrow x^2 + x - 132 = 0$. $D = 1 + 528 = 529$, $\\sqrt{D}=23$. $x = (-1+23)/2 = 11$ или $x = -12$. Натуральное только $11$.

+

Ответ: $11$ и $12$.

`); + + /* INT 1 — Шаблон «4 шага» */ + html += widget('Шаблон «4 шага»','INTERACT 1','Решим задачу пошагово. На каждом шаге выберите правильный вариант.',` +

Задача. Площадь прямоугольника равна 60 см², а одна сторона на 7 см больше другой. Найдите стороны.

+
+
+ `); + + /* INT 2 — Тренажёр задач */ + html += widget('Тренажёр текстовых задач','INTERACT 2','Решите задачу и введите ответ. После 5 задач — итог.',` +
Задача 1 / 5Очки: 0
+
+
+ + + +
+ + `); + + /* INT 3 — Конструктор задачи на движение */ + html += widget('Движение по реке','INTERACT 3','Лодка идёт по реке и обратно. Введите $v_л$ и $v_р$ — узнайте, как изменится время.',` +
+ + + +
+
`); + + /* INT 4 — Задача про двузначное число */ + html += widget('Задача про двузначное число','INTERACT 4','Сумма квадратов цифр двузначного числа равна 41, а само число равно сумме его цифр, умноженной на 6. Найдите число.',` +

Пусть $a$ — десятки, $b$ — единицы. Тогда число $= 10a + b$, $a^2 + b^2 = 41$ и $10a + b = 6(a+b)$.

+
+ + + +
+ + `); + + /* INT 5 — Drag: типы задач */ + html += widget('Классифицируем тип задачи','INTERACT 5','Прочитайте задачу — кликом отнесите её к одной из четырёх категорий.',` +
+
+
Движение
+
Работа
+
Числа
+
Геометрия
+
+
+ `); + + html += makeCard('class','Класс — решите',null,` +
    +
  1. Произведение двух последовательных нечётных чисел равно 195. Найдите их.
  2. +
  3. Длина сада на 5 м больше ширины, а площадь — 84 м². Найдите стороны.
  4. +
  5. Двое рабочих вместе закончили работу за 6 ч. Первый один сделал бы её на 5 ч быстрее, чем второй. За сколько часов сделал бы её каждый?
  6. +
`); + + html += makeCard('home','Домашка',null,` +
    +
  1. Сумма квадратов двух последовательных натуральных чисел равна 113. Найдите их.
  2. +
  3. Лодка прошла 30 км по течению и 30 км против за 4 ч. Скорость течения 1 км/ч. Найдите скорость лодки.
  4. +
  5. Найдите два числа, сумма которых 14, а произведение 48.
  6. +
`); + + html += secNav('p10','p12'); + box.innerHTML = html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box), 0); + + /* INIT 1 — Шаблон 4 шага */ + (function(){ + const steps = [ + { q:'Шаг 1. Что обозначим за $x$?', opts:['меньшую сторону','произведение','периметр','диагональ'], ok:0 }, + { q:'Шаг 2. Тогда большая сторона равна:', opts:['$x - 7$','$x + 7$','$60/x$','$7x$'], ok:1 }, + { q:'Шаг 3. Уравнение из условия $S = a \\cdot b = 60$:', opts:['$x(x+7) = 60$','$x^2 - 7 = 60$','$2x + 7 = 60$','$x/7 = 60$'], ok:0 }, + { q:'Шаг 4. После раскрытия скобок и переноса:', opts:['$x^2 + 7x - 60 = 0$','$x^2 - 7x + 60 = 0$','$x^2 + 7 = 60$','$x^2 = 67$'], ok:0 }, + { q:'Шаг 5. $D = 49 + 240 = 289 \\Rightarrow \\sqrt{D} = 17$. Корни:', opts:['$x = 5$ и $x = -12$','$x = 6$ и $x = -10$','$x = 4$ и $x = -15$','$x = 8$ и $x = -7$'], ok:0 }, + { q:'Шаг 6. Ответ:', opts:['5 см и 12 см','−12 см и 5 см','оба корня подходят','7 см и 15 см'], ok:0 }, + ]; + let i = 0; + function show(){ + const s = steps[i]; + document.getElementById('p11s-step').innerHTML = '' + (i+1) + ' / ' + steps.length + '. ' + s.q; + renderMath(document.getElementById('p11s-step')); + const opts = document.getElementById('p11s-opts'); opts.innerHTML = ''; + s.opts.forEach((o,k)=>{ + const b = document.createElement('button'); + b.className = 'btn'; b.innerHTML = o; b.style.cssText = 'text-align:left'; + b.addEventListener('click', ()=>{ + const fb = document.getElementById('p11s-fb'); fb.style.display = 'block'; + if(k === s.ok){ + b.classList.add('ok'); + feedback(fb, true, '✓'); + if(i >= steps.length - 1){ feedback(fb, true, '✓ Задача решена!'); achievement('p11_steps'); bumpProgress('p11', 18); confetti(); } + else setTimeout(()=>{ i++; show(); }, 700); + } else { b.classList.add('fail'); feedback(fb, false, 'Не то, подумайте ещё.'); } + }); + opts.appendChild(b); + }); + renderMath(opts); + document.getElementById('p11s-fb').style.display = 'none'; + } + show(); + })(); + + /* INIT 2 — Тренажёр */ + (function(){ + const tasks = [ + { q:'Произведение двух последовательных натуральных чисел равно 56. Найдите большее.', hint:'$x(x+1) = 56$', ans:[8] }, + { q:'Площадь прямоугольника 48 см², одна сторона на 2 см больше другой. Найдите меньшую.', hint:'$x(x+2)=48$', ans:[6] }, + { q:'Сумма числа и его квадрата равна 90. Найдите положительное число.', hint:'$x + x^2 = 90$', ans:[9] }, + { q:'Произведение двух чисел равно 35, а их сумма равна 12. Найдите большее.', hint:'Виета: $x_1+x_2=12,\\ x_1 x_2=35$', ans:[7] }, + { q:'Лодка прошла 12 км по течению (скорость = $v+1$) и обратно ($v-1$) за 5 ч. Найдите скорость в стоячей воде.', hint:'$\\dfrac{12}{v+1} + \\dfrac{12}{v-1} = 5$', ans:[5] }, + ]; + let cur = null, i = 1, score = 0; + function show(){ + cur = tasks[i-1]; + document.getElementById('p11t-i').textContent = i; + document.getElementById('p11t-task').innerHTML = 'Задача ' + i + '. ' + cur.q; + renderMath(document.getElementById('p11t-task')); + document.getElementById('p11t-inp').value = ''; + document.getElementById('p11t-fb').style.display = 'none'; + } + document.getElementById('p11t-start').addEventListener('click', ()=>{ i=1; score=0; document.getElementById('p11t-score').textContent = 0; show(); }); + document.getElementById('p11t-go').addEventListener('click', ()=>{ + const fb = document.getElementById('p11t-fb'); fb.style.display = 'block'; + const u = +document.getElementById('p11t-inp').value; + const ok = cur.ans.some(a => Math.abs(u - a) < 1e-6); + if(ok){ score++; feedback(fb, true, '✓'); } + else feedback(fb, false, 'Не то. Ответ: ' + cur.ans.join(' или ')); + document.getElementById('p11t-score').textContent = score; + if(i >= tasks.length){ setTimeout(()=>{ feedback(fb, score >= 3, 'Итог: ' + score + '/' + tasks.length); if(score >= 3){ achievement('p11_train'); bumpProgress('p11', 16); confetti(); } }, 600); } + else { i++; setTimeout(show, 900); } + }); + document.getElementById('p11t-hint').addEventListener('click', ()=>{ + const fb = document.getElementById('p11t-fb'); fb.style.display = 'block'; + feedback(fb, true, 'Подсказка: ' + cur.hint); renderMath(fb); + }); + })(); + + /* INIT 3 — Движение */ + (function(){ + const vlE = document.getElementById('p11m-vl'), vrE = document.getElementById('p11m-vr'), sE = document.getElementById('p11m-s'); + const out = document.getElementById('p11m-out'); + let done = false; + function refresh(){ + const vl = +vlE.value, vr = +vrE.value, s = +sE.value; + if(vl <= vr || vr < 0 || s <= 0){ out.innerHTML = 'Условие: $v_л > v_р \\geq 0,\\ S > 0$.'; renderMath(out); return; } + const t1 = s/(vl+vr), t2 = s/(vl-vr), tT = t1 + t2; + let html = '
По течению: $v = ' + (vl+vr) + '$ км/ч → $t = ' + s + '/' + (vl+vr) + ' = ' + fmt(t1) + '$ ч
'; + html += '
Против течения: $v = ' + (vl-vr) + '$ км/ч → $t = ' + fmt(t2) + '$ ч
'; + html += '
Итого время: $' + fmt(tT) + '$ ч
'; + const vAvg = 2*s/tT; + html += '
Средняя скорость: $\\dfrac{2S}{t_1+t_2} = ' + fmt(vAvg) + '$ км/ч
'; + out.innerHTML = html; renderMath(out); + if(!done){ done = true; setTimeout(()=>{ achievement('p11_move'); bumpProgress('p11', 14); }, 300); } + } + [vlE,vrE,sE].forEach(e => e.addEventListener('input', refresh)); + refresh(); + })(); + + /* INIT 4 — Задача про число */ + (function(){ + document.getElementById('p11d-check').addEventListener('click', ()=>{ + const v = +document.getElementById('p11d-inp').value; + const fb = document.getElementById('p11d-fb'); fb.style.display = 'block'; + if(v === 54){ feedback(fb, true, '✓ Верно! Число = 54.'); achievement('p11_digit'); bumpProgress('p11', 14); confetti(); } + else feedback(fb, false, 'Не то. Подсказка: $a^2 + b^2 = 41,\\ 10a+b = 6(a+b) \\Rightarrow 4a = 5b$.'); + renderMath(fb); + }); + document.getElementById('p11d-show').addEventListener('click', ()=>{ + const s = document.getElementById('p11d-sol'); + s.style.display = 'block'; + s.innerHTML = '

Шаг 1. Из $10a+b = 6(a+b)$ получаем $4a = 5b$, то есть $b = \\dfrac{4a}{5}$. Чтобы $b$ было цифрой (0..9), $a$ должно делиться на 5.

Шаг 2. $a = 5$ → $b = 4$. Проверяем: $a^2+b^2 = 25+16 = 41$. ✓

Ответ: число $= 54$.

'; + renderMath(s); + }); + })(); + + /* INIT 5 — Drag типы */ + (function(){ + const items = [ + { id:1, txt:'Лодка прошла 24 км по течению и обратно.', cat:'dv' }, + { id:2, txt:'Двое рабочих вместе закончили работу за 6 ч.', cat:'wk' }, + { id:3, txt:'Произведение последовательных чисел равно 90.', cat:'nm' }, + { id:4, txt:'Сторона квадрата увеличена на 3 см, площадь увеличилась на 33 см².', cat:'gm' }, + { id:5, txt:'Автомобиль и автобус выехали навстречу из A и B.', cat:'dv' }, + { id:6, txt:'Сумма квадратов цифр двузначного числа = 25.', cat:'nm' }, + { id:7, txt:'Бассейн наполняется одной трубой на 2 ч быстрее, чем другой.', cat:'wk' }, + { id:8, txt:'Площадь прямоугольника 48 см², а периметр 28 см.', cat:'gm' }, + ]; + const cats = ['dv','wk','nm','gm']; + const labels = { dv:'Движ.', wk:'Раб.', nm:'Числа', gm:'Геом.' }; + let placed = {}; + function makeChip(it, where){ + const wrap = document.createElement('div'); + wrap.style.cssText = 'display:inline-flex;align-items:center;gap:4px;background:var(--sec-acc-soft);border-radius:8px;padding:4px 6px;font-size:.86rem;flex-wrap:wrap;width:100%'; + const sp = document.createElement('span'); sp.textContent = it.txt; sp.style.cssText = 'padding:2px 4px;flex:1;min-width:140px'; + wrap.appendChild(sp); + if(where === 'pool'){ + cats.forEach(cat=>{ + const b = document.createElement('button'); b.className = 'btn small'; b.textContent = labels[cat]; + b.style.cssText = 'padding:3px 7px;font-size:.7rem'; + b.addEventListener('click', ()=>{ placed[it.id] = cat; render(); }); + wrap.appendChild(b); + }); + } else { + const b = document.createElement('button'); b.className = 'btn small'; b.textContent = '×'; + b.style.cssText = 'padding:2px 7px'; b.addEventListener('click', ()=>{ delete placed[it.id]; render(); }); + wrap.appendChild(b); + } + return wrap; + } + function render(){ + const pool = document.getElementById('p11c-pool'); + pool.innerHTML = ''; + items.forEach(it=>{ if(!placed[it.id]) pool.appendChild(makeChip(it, 'pool')); }); + cats.forEach(cat=>{ + const box = document.querySelector('#p11-body .drop-items[data-cat="' + cat + '"]'); + if(!box) return; + box.innerHTML = ''; + items.forEach(it=>{ if(placed[it.id] === cat) box.appendChild(makeChip(it, 'placed')); }); + }); + } + document.getElementById('p11c-check').addEventListener('click', ()=>{ + const fb = document.getElementById('p11c-fb'); fb.style.display = 'block'; + if(Object.keys(placed).length < items.length){ feedback(fb, false, '⚠ Разложите все ' + items.length + ' задач.'); return; } + let ok = 0; items.forEach(it=>{ if(placed[it.id] === it.cat) ok++; }); + if(ok === items.length){ feedback(fb, true, '✓ Все верно!'); achievement('p11_class'); bumpProgress('p11', 14); confetti(); } + else feedback(fb, false, 'Верно ' + ok + ' из ' + items.length); + }); + document.getElementById('p11c-reset').addEventListener('click', ()=>{ placed = {}; document.getElementById('p11c-fb').style.display='none'; render(); }); + render(); + })(); +} +function buildP12stub(){ buildP12(); } +function buildP12(){ + const box = document.getElementById('p12-body'); + let html = ''; + + html += makeCard('repeat','Повторение',null,` + `); + + html += makeCard('theory','Биквадратное уравнение','12.1',` +

Биквадратным называют уравнение вида $ax^4 + bx^2 + c = 0$, $a \\neq 0$.

+

Метод. Замена $t = x^2$, $t \\geq 0$. Получаем квадратное $at^2 + bt + c = 0$. Решаем его, потом для каждого $t \\geq 0$ находим $x = \\pm\\sqrt{t}$.

+
$$t = x^2 \\geq 0,\\quad x = \\pm\\sqrt{t}$$
`); + + html += makeCard('rule','Дробные → квадратные','12.2',` +
    +
  1. Найти ОДЗ (знаменатели $\\neq 0$).
  2. +
  3. Привести к общему знаменателю и умножить уравнение на него.
  4. +
  5. Решить полученное многочленное уравнение.
  6. +
  7. Отбросить посторонние корни (вне ОДЗ).
  8. +
`); + + html += makeCard('example','Примеры',null,` +

1) $x^4 - 5x^2 + 4 = 0$. Замена $t = x^2$: $t^2 - 5t + 4 = 0 \\Rightarrow t = 1$ или $t = 4$. Тогда $x = \\pm 1$ или $x = \\pm 2$. Ответ: $\\{-2;-1;1;2\\}$.

+

2) $x^4 + 3x^2 - 4 = 0$. $t^2 + 3t - 4 = 0 \\Rightarrow t = 1$ или $t = -4$. Только $t = 1$ годится: $x = \\pm 1$.

+

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$ и доведёт до конца.',` +
+ + + + +
+
`); + + /* INT 2 — Тренажёр биквадратных */ + html += widget('Тренажёр биквадратных','INTERACT 2','Решите устно. Вводите все корни через точку с запятой (или «нет»).',` +
Задача 1 / 6Очки: 0
+
+
+ + +
+ + `); + + /* INT 3 — Дробное уравнение */ + html += widget('Дробное → квадратное','INTERACT 3','По шагам решаем уравнение с дробями. Внимание к ОДЗ!',` +

Решим: $\\dfrac{x+3}{x-1} - \\dfrac{2}{x+1} = 2$

+
+
+ `); + + /* INT 4 — Какая замена */ + html += widget('Выберите подходящую замену','INTERACT 4','Для каждого уравнения подберите замену переменной.',` +
+ `); + + /* INT 5 — ОДЗ проверка */ + html += widget('Найди посторонний корень','INTERACT 5','Дано дробное уравнение с готовыми кандидатами на корни. Найдите корень, который НЕ удовлетворяет ОДЗ.',` +
+
+ + `); + + html += makeCard('class','Класс — решите',null,` +
    +
  1. $x^4 - 13x^2 + 36 = 0$
  2. +
  3. $x^4 - 5x^2 - 36 = 0$
  4. +
  5. $\\dfrac{2}{x-1} + \\dfrac{3}{x+1} = 1$
  6. +
`); + + html += makeCard('home','Домашка',null,` +
    +
  1. $x^4 - 10x^2 + 9 = 0$
  2. +
  3. $x^4 + 7x^2 - 8 = 0$
  4. +
  5. $\\dfrac{x}{x+1} - \\dfrac{1}{x-1} = \\dfrac{2}{x^2-1}$
  6. +
  7. $(x^2 - 2)^2 - 3(x^2 - 2) - 4 = 0$ (замена!)
  8. +
`); + + html += secNav('p11','final2'); + box.innerHTML = html; + if(window.renderMathInElement) setTimeout(()=>renderMath(box), 0); + + /* 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 D = b*b - 4*a*c; + html += '
D = ' + (b*b) + ' − ' + (4*a*c) + ' = ' + D + '
'; + if(D < 0){ html += '
$D < 0$ → нет $t$, значит нет $x$.
'; } + 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) + '$
'; + 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$ — не подходит
'; + }); + const u = [...new Set(roots)].sort((a,b)=>a-b); + html += '
Ответ: ' + (u.length ? '$\\{' + u.map(fmt).join(';\\ ') + '\\}$' : 'корней нет') + '
'; + } + out.innerHTML = html; renderMath(out); + achievement('p12_bi'); bumpProgress('p12', 14); + }); + })(); + + /* INIT 2 — Тренажёр биквадр */ + (function(){ + const tasks = [ + { eq:'x^4 - 5x^2 + 4 = 0', ans:[-2,-1,1,2] }, + { eq:'x^4 - 10x^2 + 9 = 0', ans:[-3,-1,1,3] }, + { eq:'x^4 - 13x^2 + 36 = 0', ans:[-3,-2,2,3] }, + { eq:'x^4 + 3x^2 - 4 = 0', ans:[-1,1] }, + { eq:'x^4 + 2x^2 + 5 = 0', ans:null }, + { eq:'x^4 - 16 = 0', ans:[-2,2] }, + ]; + let cur = null, i = 1, score = 0, shuffled = []; + function show(){ + cur = shuffled[i-1]; + document.getElementById('p12t-i').textContent = i; + document.getElementById('p12t-task').innerHTML = '$' + cur.eq + '$'; + renderMath(document.getElementById('p12t-task')); + document.getElementById('p12t-inp').value = ''; + document.getElementById('p12t-fb').style.display = 'none'; + } + function parse(s){ + s = s.trim().toLowerCase(); + if(/нет|none/.test(s)) return null; + return s.replace(/,/g,';').split(/[;\s]+/).filter(Boolean).map(Number).sort((a,b)=>a-b); + } + function check(){ + const fb = document.getElementById('p12t-fb'); fb.style.display = 'block'; + const u = parse(document.getElementById('p12t-inp').value); + let ok = false; + if(cur.ans === null) ok = u === null; + else if(u !== null){ const a = [...cur.ans].sort((x,y)=>x-y); ok = a.length === u.length && a.every((v,k)=>v === u[k]); } + if(ok){ score++; feedback(fb, true, '✓'); } + else feedback(fb, false, 'Правильно: ' + (cur.ans === null ? 'нет' : cur.ans.join('; '))); + document.getElementById('p12t-score').textContent = score; + if(i >= shuffled.length){ setTimeout(()=>{ feedback(fb, score >= 4, 'Итог: ' + score + '/' + shuffled.length); if(score >= 4){ achievement('p12_train'); bumpProgress('p12', 16); confetti(); } }, 600); } + else { i++; setTimeout(show, 900); } + } + document.getElementById('p12t-start').addEventListener('click', ()=>{ i=1; score=0; document.getElementById('p12t-score').textContent = 0; shuffled = [...tasks].sort(()=>Math.random()-0.5); show(); }); + document.getElementById('p12t-go').addEventListener('click', check); + document.getElementById('p12t-inp').addEventListener('keyup', e=>{ if(e.key === 'Enter') check(); }); + })(); + + /* INIT 3 — Дробное */ + (function(){ + const steps = [ + { q:'Шаг 1. ОДЗ:', opts:['$x \\neq 1$ и $x \\neq -1$','$x \\neq 0$','$x > 0$','любое $x$'], ok:0 }, + { q:'Шаг 2. Общий знаменатель:', opts:['$(x-1)(x+1)$','$x-1$','$x+1$','$x^2$'], ok:0 }, + { q:'Шаг 3. После умножения на ОЗ:', opts:['$(x+3)(x+1) - 2(x-1) = 2(x-1)(x+1)$','$x+3 - 2 = 2$','$(x+3) - 2 = 2(x-1)$','$x+3-2(x+1) = 2$'], ok:0 }, + { q:'Шаг 4. Раскрытие и приведение:', opts:['$x^2 + 4x + 5 = 2x^2 - 2 \\Rightarrow x^2 - 4x - 7 = 0$','$x^2 = 7$','$x^2 + 4x = 0$','$x = 5$'], ok:0 }, + { q:'Шаг 5. Корни:', opts:['$x = 2 \\pm \\sqrt{11}$','$x = 1, 7$','$x = -1, 7$','корней нет'], ok:0 }, + { q:'Шаг 6. Проверка ОДЗ ($x \\neq \\pm 1$):', opts:['оба корня подходят','$x = 2 - \\sqrt{11}$ лишний','$x = 2 + \\sqrt{11}$ лишний','оба лишние'], ok:0 }, + ]; + let i = 0; + function show(){ + const s = steps[i]; + document.getElementById('p12f-step').innerHTML = '' + (i+1) + ' / ' + steps.length + '. ' + s.q; + renderMath(document.getElementById('p12f-step')); + const opts = document.getElementById('p12f-opts'); opts.innerHTML = ''; + s.opts.forEach((o,k)=>{ + const b = document.createElement('button'); + b.className = 'btn'; b.innerHTML = o; b.style.cssText = 'text-align:left'; + b.addEventListener('click', ()=>{ + const fb = document.getElementById('p12f-fb'); fb.style.display = 'block'; + if(k === s.ok){ + b.classList.add('ok'); + feedback(fb, true, '✓'); + if(i >= steps.length - 1){ feedback(fb, true, '✓ Уравнение решено!'); achievement('p12_frac'); bumpProgress('p12', 16); confetti(); } + else setTimeout(()=>{ i++; show(); }, 700); + } else { b.classList.add('fail'); feedback(fb, false, 'Не то, подумайте.'); } + }); + opts.appendChild(b); + }); + renderMath(opts); + document.getElementById('p12f-fb').style.display = 'none'; + } + show(); + })(); + + /* INIT 4 — Замены */ + (function(){ + const items = [ + { eq:'x^4 + 3x^2 - 4 = 0', ans:'t=x^2' }, + { eq:'(x^2-3)^2 - 5(x^2-3) + 6 = 0', ans:'t=x^2-3' }, + { eq:'x^2 + \\dfrac{1}{x^2} - 4 = 0', ans:'t=x^2' }, + { eq:'(x+\\dfrac{1}{x})^2 - 3(x+\\dfrac{1}{x}) + 2 = 0', ans:'t=x+1/x' }, + ]; + const opts = ['t=x^2', 't=x^2-3', 't=x+1/x', 't=x-1']; + const pool = document.getElementById('p12s-pool'); + let answered = 0, score = 0; + items.forEach((it, idx)=>{ + const row = document.createElement('div'); + row.style.cssText = 'display:flex;gap:8px;align-items:center;padding:8px;border-bottom:1px solid var(--border);flex-wrap:wrap'; + row.innerHTML = '
$' + it.eq + '$
'; + const sel = document.createElement('select'); + sel.style.cssText = 'padding:6px;border:1.5px solid var(--border);border-radius:6px'; + sel.innerHTML = '' + opts.map(o => '').join('').replace(/\$/g,''); + const mark = document.createElement('span'); mark.style.cssText = 'font-weight:700;font-size:1.2rem;width:24px;text-align:center'; + const check = document.createElement('button'); check.className = 'btn small'; check.textContent = 'Проверить'; + check.addEventListener('click', ()=>{ + if(!sel.value){ mark.textContent = '?'; mark.style.color = 'var(--muted)'; return; } + if(sel.value === it.ans){ mark.textContent = '✓'; mark.style.color = 'var(--ok)'; if(!row.dataset.scored){ row.dataset.scored='1'; score++; answered++; } } + else { mark.textContent = '✗'; mark.style.color = 'var(--bad)'; if(!row.dataset.answered){ row.dataset.answered='1'; answered++; } } + if(answered >= items.length){ + const fb = document.getElementById('p12s-fb'); fb.style.display = 'block'; + feedback(fb, score >= 3, 'Итог: ' + score + '/' + items.length); + if(score >= 3){ achievement('p12_subst'); bumpProgress('p12', 14); confetti(); } + } + }); + row.appendChild(sel); row.appendChild(check); row.appendChild(mark); + pool.appendChild(row); + }); + if(window.renderMathInElement) renderMath(pool); + })(); + + /* INIT 5 — Посторонний корень */ + (function(){ + const tasks = [ + { eq:'\\dfrac{1}{x-2} = \\dfrac{x-2}{4}', roots:[0, 4, -2, 2], wrong:[2], odz:'x \\neq 2' }, + { eq:'\\dfrac{x}{x-3} = \\dfrac{9}{x-3}', roots:[3, 9, -9, 0], wrong:[3], odz:'x \\neq 3' }, + { eq:'\\dfrac{1}{x+1} + \\dfrac{1}{x-1} = 0', roots:[1, -1, 0, 2], wrong:[1,-1], odz:'x \\neq \\pm 1' }, + ]; + let cur = null, i = 1; + function show(){ + cur = tasks[i-1]; + document.getElementById('p12o-task').innerHTML = 'Уравнение ' + i + ' / ' + tasks.length + ': $' + cur.eq + '$
ОДЗ: $' + cur.odz + '$
Кандидаты на корни:'; + renderMath(document.getElementById('p12o-task')); + const opts = document.getElementById('p12o-opts'); opts.innerHTML = ''; + cur.roots.forEach(r=>{ + const b = document.createElement('button'); b.className = 'btn'; b.textContent = 'x = ' + r; + b.addEventListener('click', ()=>{ + const fb = document.getElementById('p12o-fb'); fb.style.display = 'block'; + if(cur.wrong.includes(r)){ b.classList.add('ok'); feedback(fb, true, '✓ Это посторонний корень (не в ОДЗ).'); } + else { b.classList.add('fail'); feedback(fb, false, 'Не то — этот корень допустим в ОДЗ. Ищите тот, что нарушает.'); return; } + if(i >= tasks.length){ setTimeout(()=>{ feedback(fb, true, 'Все 3 пройдено!'); achievement('p12_odz'); bumpProgress('p12', 14); confetti(); }, 500); } + else { i++; setTimeout(show, 800); } + }); + opts.appendChild(b); + }); + document.getElementById('p12o-fb').style.display = 'none'; + } + document.getElementById('p12o-start').addEventListener('click', ()=>{ i=1; show(); }); + })(); +} function buildFinal2stub(){ document.getElementById('final2-body').innerHTML = `

Финал главы

Итоговая самооценка, практика, увлекательная математика и финальный босс — в Wave 4.

${secNav('p12',null)}`; }