From c931eeacd6bfc6afc920aca55a10f5ad7d8fe54d Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Fri, 29 May 2026 12:05:15 +0300 Subject: [PATCH] =?UTF-8?q?feat(alg11=20ch2=20wave3=20+=20final):=20=C2=A7?= =?UTF-8?q?6=20=C2=AB=D0=9F=D0=BE=D0=BA=D0=B0=D0=B7=D0=B0=D1=82=D0=B5?= =?UTF-8?q?=D0=BB=D1=8C=D0=BD=D1=8B=D0=B5=20=D0=BD=D0=B5=D1=80=D0=B0=D0=B2?= =?UTF-8?q?=D0=B5=D0=BD=D1=81=D1=82=D0=B2=D0=B0=C2=BB=20+=20=D0=A4=D0=B8?= =?UTF-8?q?=D0=BD=D0=B0=D0=BB=20=D0=93=D0=BB=D0=B0=D0=B2=D1=8B=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §6 — 3 makeCard (теория правила знаков, алгоритм, замена переменной) + 4 интерактива: пошаговый решатель с числовой прямой SVG, калькулятор a^(kx+b) sg c с учётом монотонности и знака k, квикфайр «сохраняется/меняется» (8), тренажёр границ интервала (6). Финал 2 — 3 mini-карточки шпаргалки (§4/§5/§6) + 5 боссов (Циклоп Показательной, Минотавр Уравнений, Гарпия Неравенств, Дракон Замены, Мастер Показательной) с прогресс-баром, ачивкой ch2_done «Магистр показательной функции» + 50 XP бонус. Co-Authored-By: Claude Haiku 4.5 --- frontend/textbooks/algebra_11_ch2.html | 702 ++++++++++++++++++++++++- 1 file changed, 689 insertions(+), 13 deletions(-) diff --git a/frontend/textbooks/algebra_11_ch2.html b/frontend/textbooks/algebra_11_ch2.html index e1ce5b4..b06e806 100644 --- a/frontend/textbooks/algebra_11_ch2.html +++ b/frontend/textbooks/algebra_11_ch2.html @@ -1459,31 +1459,707 @@ function buildP5(){ function buildP6(){ const box = document.getElementById('p6-body'); let html = ''; - html += makeCard('theory', 'В разработке', '6.0', ` -

Содержание параграфа Показательные неравенства будет добавлено в Phase 1+.

-

Раздел Phase 0 — skeleton. Здесь появятся теория, примеры и интерактивы.

-

Ключевая формула: $a^x > b$

- `); + + /* === ТЕОРИЯ === */ + + html += makeCard('theory', 'Основное правило', '6.1', ` +

Показательным неравенством называется неравенство вида $a^{f(x)} > a^{g(x)}$ (или $<$, $\\ge$, $\\le$), где $a > 0$, $a \\ne 1$.

+

Поскольку функция $y = a^x$ монотонна (см. §4), при переходе от степеней к показателям всё зависит от того, возрастает она или убывает:

+

+ $a^{f(x)} > a^{g(x)} \\;\\Leftrightarrow\\; \\begin{cases} f(x) > g(x), & \\text{если } a > 1, \\\\ f(x) < g(x), & \\text{если } 0 < a < 1. \\end{cases}$ +

+

Запомни:

+ +

Это правило — прямое следствие монотонности показательной функции (см. §4).

`); + + html += makeCard('rule', 'Алгоритм решения', '6.2', ` +

Алгоритм похож на алгоритм для уравнений из §5, но требует постоянного контроля знака неравенства:

+
    +
  1. Привести обе части к степени с одинаковым основанием $a$.
  2. +
  3. Сравнить значение $a$ с единицей и записать неравенство показателей с правильным знаком.
  4. +
  5. Решить полученное неравенство для $x$ и записать ответ интервалом.
  6. +
+

Пример 1. $2^{x-1} > 8$.

+

$8 = 2^3$, поэтому $2^{x-1} > 2^3$. Основание $a = 2 > 1$ — знак сохраняется: $x - 1 > 3 \\Rightarrow x > 4$.

+

Ответ: $x \\in (4;\\;+\\infty)$.

+

Пример 2. $\\left(\\dfrac{1}{3}\\right)^x \\ge 9$.

+

$9 = 3^2 = \\left(\\dfrac{1}{3}\\right)^{-2}$. Тогда $\\left(\\dfrac{1}{3}\\right)^x \\ge \\left(\\dfrac{1}{3}\\right)^{-2}$. Основание $a = \\dfrac{1}{3} < 1$ — знак меняется: $x \\le -2$.

+

Ответ: $x \\in (-\\infty;\\;-2]$.

`); + + html += makeCard('example', 'Метод замены переменной', '6.3', ` +

Если неравенство содержит $a^{2x}$ и $a^x$, делаем замену $t = a^x$, причём обязательно $t > 0$. Получаем алгебраическое неравенство (чаще квадратное), которое решаем методом интервалов.

+

+ $A \\cdot a^{2x} + B \\cdot a^x + C \\;\\gtrless\\; 0 \\;\\xrightarrow{\\;t = a^x > 0\\;}\\; A t^2 + B t + C \\;\\gtrless\\; 0$ +

+

Алгоритм:

+
    +
  1. Сделать замену $t = a^x$, $t > 0$.
  2. +
  3. Решить полученное неравенство для $t$ методом интервалов.
  4. +
  5. Пересечь полученное множество с условием $t > 0$.
  6. +
  7. Вернуться к $x$ из $a^x \\in [\\,t_1;\\,t_2\\,]$ с учётом монотонности.
  8. +
+

Пример. $4^x - 5 \\cdot 2^x + 4 \\le 0$.

+

Замечаем $4^x = (2^x)^2$. Замена $t = 2^x > 0$: $t^2 - 5t + 4 \\le 0$. Корни $t = 1$, $t = 4$, значит $t \\in [1;\\;4]$ (оба положительны — условие выполнено).

+

Возвращаемся: $1 \\le 2^x \\le 4 \\Leftrightarrow 2^0 \\le 2^x \\le 2^2$. Основание $2 > 1$ — знак сохраняется: $0 \\le x \\le 2$.

+

Ответ: $x \\in [0;\\;2]$.

`); + + /* === ИНТЕРАКТИВЫ === */ + + /* IV1 — решатель показательных неравенств с шагами и числовой прямой */ + html += `
+
ИНТЕРАКТИВ 1
Решатель показательных неравенств
+
Выбери задачу ползунком и нажимай «Следующий шаг ▶». В конце появится ответ на числовой прямой. Просмотри все 5 задач — получишь XP.
+
+ +
+
+
+ +
+ + + +
+
`; + + /* IV2 — калькулятор a^(kx+b) > c */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор $a^{kx+b} \\gtrless c$
+
Введи $a$, $k$, $b$, $c$ и выбери знак неравенства. Калькулятор подскажет, сохраняется или меняется знак, и выдаст ответ интервалом.
+
+ $a$ = + + $k$ = + + $b$ = + + знак + + $c$ = + + +
+
+ Примеры: + + + + +
+
+ +
`; + + /* IV3 — знак сохраняется или меняется? */ + html += `
+
ИНТЕРАКТИВ 3
Сохраняется или меняется?
+
Глядя на основание степени, определи, что произойдёт со знаком неравенства при переходе к показателям. 8 заданий.
+
Задача 1 / 8Очки: 0 / 8
+
+
+ +
+
`; + + /* IV4 — тренажёр неравенств */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр неравенств
+
Реши неравенство и введи границу интервала ответа (например, для $x > 3$ ввести $3$; для $x \\in [0;\\,2]$ ввести любую границу — указано в задании). Допуск $\\pm 0{,}05$. 6 задач.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ граница = + + + +
+ +
`; + html += secNavFor('p6'); html += readButton('p6'); + box.innerHTML = html; renderMath(box); + + /* === IV1 — решатель с шагами и числовой прямой === */ + (function(){ + /* line: {min, max, lo, hi, openLo, openHi, dirLeft, dirRight} + dirLeft/dirRight — стрелка уходит влево/вправо за границу видимой части */ + const TASKS = [ + { + q: '$2^x > 8$', + steps: [ + 'Приводим к одному основанию: $8 = 2^3$, поэтому $2^x > 2^3$.', + 'Основание $a = 2 > 1$ — знак сохраняется: $x > 3$.', + 'Ответ: $x \\in (3;\\;+\\infty)$.' + ], + line: { min:-2, max:8, lo:3, hi:null, openLo:true, dirRight:true } + }, + { + q: '$\\left(\\dfrac{1}{2}\\right)^x \\ge 4$', + steps: [ + 'Приводим к одному основанию: $4 = 2^2 = \\left(\\dfrac{1}{2}\\right)^{-2}$.', + 'Получаем $\\left(\\dfrac{1}{2}\\right)^x \\ge \\left(\\dfrac{1}{2}\\right)^{-2}$.', + 'Основание $a = \\dfrac{1}{2} < 1$ — знак меняется: $x \\le -2$.', + 'Ответ: $x \\in (-\\infty;\\;-2]$.' + ], + line: { min:-7, max:3, lo:null, hi:-2, openHi:false, dirLeft:true } + }, + { + q: '$3^{x+1} < 27$', + steps: [ + 'Приводим к одному основанию: $27 = 3^3$, поэтому $3^{x+1} < 3^3$.', + 'Основание $a = 3 > 1$ — знак сохраняется: $x + 1 < 3$.', + 'Откуда $x < 2$.', + 'Ответ: $x \\in (-\\infty;\\;2)$.' + ], + line: { min:-3, max:7, lo:null, hi:2, openHi:true, dirLeft:true } + }, + { + q: '$4^x - 5 \\cdot 2^x + 4 \\le 0$', + steps: [ + 'Замечаем $4^x = (2^x)^2$. Замена $t = 2^x$, $t > 0$.', + 'Получаем квадратное: $t^2 - 5t + 4 \\le 0$. Корни $t = 1$, $t = 4$.', + 'Решение по $t$: $t \\in [1;\\;4]$ (оба положительны).', + 'Возвращаемся: $1 \\le 2^x \\le 4$, то есть $2^0 \\le 2^x \\le 2^2$. Знак сохраняется: $0 \\le x \\le 2$.', + 'Ответ: $x \\in [0;\\;2]$.' + ], + line: { min:-2, max:5, lo:0, hi:2, openLo:false, openHi:false } + }, + { + q: '$\\left(\\dfrac{1}{3}\\right)^{x-1} > 9$', + steps: [ + 'Приводим к одному основанию: $9 = 3^2 = \\left(\\dfrac{1}{3}\\right)^{-2}$.', + 'Получаем $\\left(\\dfrac{1}{3}\\right)^{x-1} > \\left(\\dfrac{1}{3}\\right)^{-2}$.', + 'Основание $a = \\dfrac{1}{3} < 1$ — знак меняется: $x - 1 < -2$.', + 'Откуда $x < -1$.', + 'Ответ: $x \\in (-\\infty;\\;-1)$.' + ], + line: { min:-6, max:4, lo:null, hi:-1, openHi:true, dirLeft:true } + } + ]; + + function drawLine(L){ + const W = 420, H = 84, padL = 24, padR = 24; + const y = 44; + const lo = (L.lo!=null) ? L.lo : L.min; + const hi = (L.hi!=null) ? L.hi : L.max; + const span = L.max - L.min; + const toX = v => padL + (v - L.min) * (W - padL - padR) / span; + let s = ''; + // главная ось + s += ''; + s += ''; + // тики и подписи + for(let v = Math.ceil(L.min); v <= Math.floor(L.max); v++){ + const x = toX(v); + s += ''; + s += ''+v+''; + } + // закрашенная область + const xLo = toX(lo), xHi = toX(hi); + let x1 = xLo, x2 = xHi; + if(L.dirLeft){ x1 = padL + 2; } + if(L.dirRight){ x2 = W - padR - 2; } + s += ''; + if(L.dirLeft){ + s += ''; + } + if(L.dirRight){ + s += ''; + } + // граничные точки + if(L.lo != null){ + const fill = L.openLo ? '#fff' : '#7c3aed'; + s += ''; + s += ''+L.lo+''; + } + if(L.hi != null){ + const fill = L.openHi ? '#fff' : '#7c3aed'; + s += ''; + s += ''+L.hi+''; + } + s += ''; + return s; + } + + const sn = document.getElementById('p6-iv1-sn'); + const nL = document.getElementById('p6-iv1-n'); + const qEl = document.getElementById('p6-iv1-q'); + const stepsEl = document.getElementById('p6-iv1-steps'); + const lineEl = document.getElementById('p6-iv1-line'); + const nextBtn = document.getElementById('p6-iv1-next'); + const allBtn = document.getElementById('p6-iv1-all'); + const resetBtn = document.getElementById('p6-iv1-reset'); + const seen = new Set(); + let _done = false; + let cur = 0, shown = 1; + + function render(){ + const t = TASKS[cur]; + nL.textContent = (cur + 1); + qEl.innerHTML = t.q; + stepsEl.innerHTML = t.steps.map((s, i) => { + const visible = i < shown; + const isLast = i === t.steps.length - 1 && visible; + const bg = isLast ? '#dcfce7' : 'var(--card)'; + const brd = isLast ? '2px solid #16a34a' : '1px solid var(--border)'; + return '
Шаг '+(i+1)+':'+s+'
'; + }).join(''); + renderMath(qEl); + renderMath(stepsEl); + if(shown >= t.steps.length){ + lineEl.innerHTML = '
Ответ на числовой прямой:
' + drawLine(t.line); + lineEl.style.display = 'block'; + seen.add(cur); + if(!_done && seen.size >= 5){ _done = true; addXp(10, 'p6-iv1'); bumpProgress('p6', 15); } + } else { + lineEl.style.display = 'none'; + } + } + function load(n){ cur = Math.max(0, Math.min(TASKS.length - 1, n)); shown = 1; render(); } + sn.addEventListener('input', () => load((+sn.value) - 1)); + nextBtn.addEventListener('click', () => { + if(shown < TASKS[cur].steps.length){ shown++; render(); } + }); + allBtn.addEventListener('click', () => { shown = TASKS[cur].steps.length; render(); }); + resetBtn.addEventListener('click', () => { shown = 1; render(); }); + load(0); + })(); + + /* === IV2 — калькулятор a^(kx+b) > c === */ + (function(){ + const aI = document.getElementById('p6-iv2-a'); + const kI = document.getElementById('p6-iv2-k'); + const bI = document.getElementById('p6-iv2-b'); + const sgI = document.getElementById('p6-iv2-sg'); + const cI = document.getElementById('p6-iv2-c'); + const go = document.getElementById('p6-iv2-go'); + const out = document.getElementById('p6-iv2-out'); + const fb = document.getElementById('p6-iv2-fb'); + const used = new Set(); + let _done = false; + + document.querySelectorAll('#p6-iv2 [data-set]').forEach(btn => { + btn.addEventListener('click', () => { + const v = btn.dataset.set.split(','); + aI.value = v[0]; kI.value = v[1]; bI.value = v[2]; sgI.value = v[3]; cI.value = v[4]; + calc(); + }); + }); + + const SIGN_TEX = { gt:'>', ge:'\\ge', lt:'<', le:'\\le' }; + const SIGN_INT = { gt:'(', ge:'[', lt:')', le:']' }; + // переворот знака неравенства при умножении/делении на отрицательное + function flipSign(s){ return ({gt:'lt',ge:'le',lt:'gt',le:'ge'})[s]; } + + function calc(){ + const a = parseFloat(aI.value); + const k = parseFloat(kI.value); + const b = parseFloat(bI.value); + const c = parseFloat(cI.value); + const sg = sgI.value; + if(![a,k,b,c].every(isFinite)){ feedback(fb, false, '✗ Введи все четыре числа.'); return; } + if(a <= 0 || Math.abs(a - 1) < 1e-9){ feedback(fb, false, '✗ Основание $a$ должно быть $> 0$ и $\\ne 1$.'); return; } + if(k === 0){ feedback(fb, false, '✗ При $k = 0$ показатель не зависит от $x$.'); return; } + + const expTex = (k===1?'':k) + 'x' + (b>0?'+'+b:(b<0?b:'')); + const ineq = '$' + a + '^{' + expTex + '} ' + SIGN_TEX[sg] + ' ' + c + '$'; + let html = '
Неравенство: '+ineq+'
'; + + // Случай c <= 0 — левая часть всегда > 0 + if(c <= 0){ + if(sg === 'gt' || sg === 'ge'){ + html += '
Левая часть $a^{kx+b} > 0$ при любых $x$, а правая $\\le 0$. Значит неравенство верно при всех $x \\in \\mathbb{R}$.
'; + } else { + html += '
Левая часть $a^{kx+b} > 0$, а требуется $\\le c \\le 0$. Решений нет.
'; + } + out.innerHTML = html; + renderMath(out); + feedback(fb, true, '✓ Решено: см. ответ выше.'); + used.add(aI.value+','+kI.value+','+bI.value+','+sgI.value+','+cI.value); + if(!_done && used.size >= 4){ _done = true; addXp(10, 'p6-iv2'); bumpProgress('p6', 15); } + return; + } + + // Анализ монотонности + let sgEff = sg; + if(a < 1){ + html += '
Основание $a = '+a+' < 1$ — функция убывает, знак неравенства МЕНЯЕТСЯ.
'; + sgEff = flipSign(sgEff); + } else { + html += '
Основание $a = '+a+' > 1$ — функция возрастает, знак неравенства сохраняется.
'; + } + + // Степень + let intLog = null; + for(let p = -10; p <= 12; p++){ + if(Math.abs(Math.pow(a, p) - c) < 1e-9){ intLog = p; break; } + } + let rhsTex; + if(intLog !== null){ + html += '
$'+c+' = '+a+'^{'+intLog+'}$, поэтому неравенство показателей: $'+expTex+' '+SIGN_TEX[sgEff]+' '+intLog+'$.
'; + rhsTex = String(intLog); + } else { + rhsTex = '\\log_{'+a+'} '+c; + html += '
Неравенство показателей: $'+expTex+' '+SIGN_TEX[sgEff]+' \\log_{'+a+'} '+c+'$.
'; + } + + // Решаем kx + b [sgEff] R, где R = intLog (или log_a c) + // x [?] (R - b) / k. Если k<0, знак ещё раз меняется. + let sgFinal = sgEff; + if(k < 0){ + html += '
Делим на $k = '+k+' < 0$ — знак снова меняется.
'; + sgFinal = flipSign(sgFinal); + } + + const xNum = (intLog !== null) ? (intLog - b) : (Math.log(c)/Math.log(a) - b); + const xVal = xNum / k; + const xStr = (Math.abs(xVal - Math.round(xVal)) < 1e-9) ? String(Math.round(xVal)) : (+xVal.toFixed(4)).toString(); + + // Формируем интервал + let interval; + if(sgFinal === 'gt') interval = '('+xStr+';\\,+\\infty)'; + else if(sgFinal === 'ge') interval = '['+xStr+';\\,+\\infty)'; + else if(sgFinal === 'lt') interval = '(-\\infty;\\,'+xStr+')'; + else interval = '(-\\infty;\\,'+xStr+']'; + + html += '
$\\Rightarrow\\; x '+SIGN_TEX[sgFinal]+' '+xStr+',\\quad x \\in '+interval+'$
'; + + out.innerHTML = html; + renderMath(out); + feedback(fb, true, '✓ Решено.'); + used.add(aI.value+','+kI.value+','+bI.value+','+sgI.value+','+cI.value); + if(!_done && used.size >= 4){ _done = true; addXp(10, 'p6-iv2'); bumpProgress('p6', 15); } + } + go.addEventListener('click', calc); + [aI, kI, bI, cI].forEach(i => i.addEventListener('keydown', e => { if(e.key === 'Enter') calc(); })); + calc(); + })(); + + /* === IV3 — сохраняется или меняется? === */ + (function(){ + const OPTS = ['Сохраняется', 'Меняется']; + const Q = [ + { q: '$2^{f(x)} > 2^{g(x)}$', ans: 0, hint: 'Основание $2 > 1$ — функция возрастает, знак сохраняется.' }, + { q: '$\\left(\\dfrac{1}{3}\\right)^{f(x)} > \\left(\\dfrac{1}{3}\\right)^{g(x)}$', ans: 1, hint: 'Основание $\\dfrac{1}{3} < 1$ — функция убывает, знак меняется.' }, + { q: '$5^x < 25$', ans: 0, hint: 'Приводим: $5^x < 5^2$. Основание $5 > 1$ — знак сохраняется.' }, + { q: '$\\left(\\dfrac{1}{2}\\right)^x > 8$', ans: 1, hint: 'Приводим: $\\left(1/2\\right)^x > \\left(1/2\\right)^{-3}$. Основание $< 1$ — знак меняется.' }, + { q: '$0{,}1^x \\le 0{,}01$', ans: 1, hint: 'Приводим: $0{,}1^x \\le 0{,}1^2$. Основание $0{,}1 < 1$ — знак меняется.' }, + { q: '$3^x \\ge 27$', ans: 0, hint: 'Приводим: $3^x \\ge 3^3$. Основание $3 > 1$ — знак сохраняется.' }, + { q: '$10^x > 100$', ans: 0, hint: 'Приводим: $10^x > 10^2$. Основание $10 > 1$ — знак сохраняется.' }, + { q: '$\\left(\\dfrac{2}{5}\\right)^x < 1$', ans: 1, hint: 'Приводим: $\\left(2/5\\right)^x < \\left(2/5\\right)^0$. Основание $< 1$ — знак меняется.' }, + ]; + let i = 0, score = 0; + const qEl = document.getElementById('p6-iv3-q'); + const oEl = document.getElementById('p6-iv3-opts'); + const fb = document.getElementById('p6-iv3-fb'); + const iEl = document.getElementById('p6-iv3-i'); + const sEl = document.getElementById('p6-iv3-s'); + + function show(){ + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: '+score+' / '+Q.length; + oEl.innerHTML = ''; + if(score === Q.length){ addXp(15, 'p6-iv3'); bumpProgress('p6', 25); } + else if(score >= 6){ addXp(8, 'p6-iv3'); bumpProgress('p6', 15); } + return; + } + iEl.textContent = (i + 1); + sEl.textContent = score; + const item = Q[i]; + qEl.innerHTML = 'Знак неравенства при переходе к показателям: ' + item.q; + oEl.innerHTML = OPTS.map((m, k) => '').join(''); + fb.style.display = 'none'; + renderMath(qEl); + oEl.querySelectorAll('button').forEach(b => { + b.addEventListener('click', () => { + const k = +b.dataset.k; + if(k === item.ans){ score++; feedback(fb, true, '✓ Верно! '+item.hint+' Дальше ▶'); } + else feedback(fb, false, '✗ Неверно. Правильно: '+OPTS[item.ans]+'. '+item.hint+' Дальше ▶'); + sEl.textContent = score; + oEl.querySelectorAll('button').forEach(x => x.disabled = true); + i++; + setTimeout(show, 1500); + }); + }); + } + document.getElementById('p6-iv3-restart').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + + /* === IV4 — тренажёр неравенств === */ + (function(){ + const Q = [ + { q: '$2^x > 16$ — введи границу', ans: 4, hint: '$2^x > 2^4 \\Rightarrow x > 4$. Граница — $4$.' }, + { q: '$\\left(\\dfrac{1}{3}\\right)^x \\ge 9$ — введи границу', ans: -2, hint: '$\\left(1/3\\right)^x \\ge \\left(1/3\\right)^{-2}$. Знак меняется: $x \\le -2$. Граница — $-2$.' }, + { q: '$5^x < 1$ — введи границу', ans: 0, hint: '$5^x < 5^0$. Знак сохраняется: $x < 0$. Граница — $0$.' }, + { q: '$3^{x-1} \\le 81$ — введи границу', ans: 5, hint: '$3^{x-1} \\le 3^4 \\Rightarrow x - 1 \\le 4 \\Rightarrow x \\le 5$. Граница — $5$.' }, + { q: '$\\left(\\dfrac{1}{2}\\right)^x > 0{,}25$ — введи границу', ans: 2, hint: '$\\left(1/2\\right)^x > \\left(1/2\\right)^2$. Знак меняется: $x < 2$. Граница — $2$.' }, + { q: '$4^x \\ge 8$ — введи границу', ans: 1.5, hint: '$2^{2x} \\ge 2^3 \\Rightarrow 2x \\ge 3 \\Rightarrow x \\ge 1{,}5$. Граница — $1{,}5$.' }, + ]; + let i = 0, score = 0; + function show(){ + const qEl = document.getElementById('p6-iv4-q'); + const iEl = document.getElementById('p6-iv4-i'); + const sEl = document.getElementById('p6-iv4-s'); + const fb = document.getElementById('p6-iv4-fb'); + const ansI = document.getElementById('p6-iv4-ans'); + if(i >= Q.length){ + qEl.innerHTML = 'Готово! Результат: '+score+' / '+Q.length; + if(score === Q.length){ addXp(15, 'p6-iv4'); bumpProgress('p6', 25); } + else if(score >= 4){ addXp(8, 'p6-iv4'); bumpProgress('p6', 15); } + return; + } + iEl.textContent = (i + 1); + sEl.textContent = score; + qEl.innerHTML = Q[i].q; + ansI.value = ''; + renderMath(qEl); + fb.style.display = 'none'; + } + function go(){ + if(i >= Q.length) return; + const fb = document.getElementById('p6-iv4-fb'); + const raw = document.getElementById('p6-iv4-ans').value.replace(',', '.'); + const ans = parseFloat(raw); + if(isNaN(ans)){ feedback(fb, false, '✗ Введи число.'); return; } + if(Math.abs(ans - Q[i].ans) < 0.05){ + score++; + feedback(fb, true, '✓ Верно! '+Q[i].hint+' Дальше ▶'); + } else { + feedback(fb, false, '✗ Неверно. Граница: $'+Q[i].ans+'$. '+Q[i].hint+' Дальше ▶'); + } + document.getElementById('p6-iv4-s').textContent = score; + i++; + setTimeout(show, 1500); + } + document.getElementById('p6-iv4-go').addEventListener('click', go); + document.getElementById('p6-iv4-ans').addEventListener('keydown', e => { if(e.key === 'Enter') go(); }); + document.getElementById('p6-iv4-start').addEventListener('click', () => { i = 0; score = 0; show(); }); + show(); + })(); + wireReadBtn('p6'); } function buildFinal2(){ const box = document.getElementById('final2-body'); let html = ''; - html += makeCard('theory', 'В разработке', '★.0', ` -

Содержание финала главы Финал главы будет добавлено в Phase 1+.

-

Раздел Phase 0 — skeleton. Здесь появятся теория, примеры и интерактивы.

-

Ключевая формула: Итоги · боссы главы 2

- `); - html += secNavFor('final2'); - html += readButton('final2'); + + /* Часть А — Шпаргалка главы (3 mini-карточки) */ + html += `
+
+
${ICONS.theory}
+
Шпаргалка главы 2
+
Итог
+
+
+

Ключевые формулы и идеи всех трёх параграфов в одном месте — просмотри перед битвой с боссами.

+
+
+
+ +
§ 4 · Показ. функция
+
+
$y = a^x$ ($a > 0$, $a \\ne 1$). $D = \\mathbb{R}$, $E = (0;\\,+\\infty)$. При $a > 1$ — возрастает, при $0 < a < 1$ — убывает. Через $(0;\\,1)$. Асимптота $y = 0$.
+
+
+
+ +
§ 5 · Показ. уравнения
+
+
$a^{f(x)} = a^{g(x)} \\Leftrightarrow f(x) = g(x)$. Четыре метода: одинаковое основание, замена переменной ($t = a^x > 0$), однородные, графический.
+
+
+
+ +
§ 6 · Показ. неравенства
+
+
При $a > 1$ знак сохраняется, при $0 < a < 1$ — меняется. Замена $t = a^x > 0$ — обязательно учитывать положительность.
+
+
+
+
`; + + /* Часть Б — 5 боссов (intro) */ + html += `
+
+
${ICONS.rule}
+
Боссы главы 2
+
5
+
+
+

5 интегрированных задач по всей главе. За каждого побеждённого босса: +10 XP, +18% к прогрессу. Победишь всех — ачивка «Магистр показательной функции» и +50 XP бонус.

+
+
`; + + html += '
'; + + html += `
+
Прогресс по боссам
+
0 / 5 боссов побеждено
+
+
+
+ +
`; + + html += secNav('p6', null); + box.innerHTML = html; renderMath(box); - wireReadBtn('final2'); + + /* Боссы */ + const BOSSES = [ + { + n:1, color:'#10b981', + title:'Циклоп Показательной', + tag:'§ 4', + q:'Найдите значение функции $y = 3^x$ при $x = -2$. Введите ответ числом (допуск $\\pm 0{,}05$).', + ans:1/9, + hint:'$3^{-2} = \\dfrac{1}{3^2} = \\dfrac{1}{9} \\approx 0{,}11$.' + }, + { + n:2, color:'#0891b2', + title:'Минотавр Уравнений', + tag:'§ 5', + q:'Решите уравнение $5^{2x-1} = 125$. Введите $x$.', + ans:2, + hint:'$125 = 5^3$, поэтому $2x - 1 = 3 \\Rightarrow x = 2$.' + }, + { + n:3, color:'#7c3aed', + title:'Гарпия Неравенств', + tag:'§ 6', + q:'Решите $\\left(\\dfrac{1}{2}\\right)^x > 32$. Введите наибольшее целое $x$.', + ans:-6, + hint:'$\\left(1/2\\right)^x > \\left(1/2\\right)^{-5}$. Знак меняется: $x < -5$. Наибольшее целое — $-6$.' + }, + { + n:4, color:'#dc2626', + title:'Дракон Замены', + tag:'§ 5 + § 6', + q:'Найдите сумму корней уравнения $9^x - 10 \\cdot 3^x + 9 = 0$.', + ans:2, + hint:'Замена $t = 3^x$: $t^2 - 10t + 9 = 0 \\Rightarrow t = 1$ или $t = 9$. $x = 0$ и $x = 2$. Сумма — $2$.' + }, + { + n:5, color:'#f59e0b', + title:'Мастер Показательной', + tag:'§ 4 + § 5 + § 6', + q:'При каком $a$ функция $y = (3a - 5)^x$ убывает на $\\mathbb{R}$? Найдите сумму целых значений $a$ из найденного интервала.', + ans:0, + hint:'Убывает при $0 < 3a - 5 < 1$, то есть $\\dfrac{5}{3} < a < 2$. Целых $a$ в этом интервале нет — сумма равна $0$.' + }, + ]; + + const cont = document.getElementById('ch2-bosses-container'); + const STATE_KEY = 'algebra11_ch2_bosses'; + const BOSS_STATE = (function(){ + try{ const s = localStorage.getItem(STATE_KEY); if(s){ const p = JSON.parse(s); if(Array.isArray(p) && p.length === BOSSES.length) return p; } }catch(e){} + return BOSSES.map(()=>({defeated:false})); + })(); + function saveBosses(){ try{ localStorage.setItem(STATE_KEY, JSON.stringify(BOSS_STATE)); }catch(e){} } + + cont.innerHTML = BOSSES.map((b, idx)=>{ + return '
' + +'
' + +'' + +'
Босс '+b.n+': '+b.title+'
' + +'
'+b.tag+'
' + +'
' + +'
'+b.q+'
' + +'
' + +'ответ =' + +'' + +'' + +'' + +'
' + +'' + +'
'; + }).join(''); + renderMath(cont); + + function refreshOverall(){ + const won = BOSS_STATE.filter(s => s.defeated).length; + const txt = document.getElementById('ch2-boss-overall'); + const fill = document.getElementById('ch2-boss-overall-fill'); + if(txt) txt.textContent = won + ' / ' + BOSSES.length + ' боссов побеждено'; + if(fill) fill.style.width = (won * 100 / BOSSES.length) + '%'; + if(won >= BOSSES.length){ + const reward = document.getElementById('ch2-final-reward'); + if(reward && reward.style.display === 'none'){ + reward.style.display = 'block'; + if(!STATE.achievements.has('ch2_done')){ + achievement('ch2_done','Магистр показательной функции'); + addXp(50, 'ch2-bonus'); + bumpProgress('final2', 30); + if(window.confetti){ try{ confetti(); }catch(e){} } + } + } + } + } + + BOSSES.forEach((b, idx)=>{ + const card = document.getElementById('boss2-'+b.n+'-card'); + const goBtn = document.getElementById('boss2-'+b.n+'-go'); + const hintBtn = document.getElementById('boss2-'+b.n+'-hint'); + const ansInp = document.getElementById('boss2-'+b.n+'-ans'); + if(BOSS_STATE[idx].defeated){ + card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))'; + card.classList.add('glow'); + goBtn.disabled = true; goBtn.style.opacity = .55; goBtn.textContent = '✓ Повержен'; + ansInp.disabled = true; + } + goBtn.addEventListener('click', ()=>{ + if(BOSS_STATE[idx].defeated) return; + const fb = document.getElementById('boss2-'+b.n+'-fb'); + const raw = ansInp.value.replace(',', '.'); + const val = parseFloat(raw); + if(isNaN(val)){ feedback(fb, false, '✗ Введи число.'); return; } + if(Math.abs(val - b.ans) < 0.05){ + BOSS_STATE[idx].defeated = true; saveBosses(); + feedback(fb, true, '✓ Босс '+b.n+' повержен! +10 XP. '+b.hint); + addXp(10, 'boss-ch2-'+b.n); + bumpProgress('final2', 18); + goBtn.disabled = true; goBtn.style.opacity = .55; goBtn.textContent = '✓ Повержен'; + ansInp.disabled = true; + card.style.background = 'linear-gradient(135deg,var(--sec-acc-soft),var(--pri-soft))'; + card.classList.add('glow','pulse'); + setTimeout(()=>card.classList.remove('pulse'), 900); + refreshOverall(); + } else { + feedback(fb, false, '✗ Промах. Попробуй ещё. Подсказка доступна.'); + } + }); + hintBtn.addEventListener('click', ()=>{ + const fb = document.getElementById('boss2-'+b.n+'-fb'); + fb.className = 'feedback ok'; + fb.innerHTML = 'Подсказка: '+b.hint; + fb.style.display = 'block'; + fb.style.background = 'var(--warn-bg)'; + fb.style.color = '#92400e'; + fb.style.borderLeftColor = 'var(--warn)'; + renderMath(fb); + }); + ansInp.addEventListener('keydown', e=>{ if(e.key === 'Enter') goBtn.click(); }); + }); + + refreshOverall(); } /* ===== Search ===== */