diff --git a/frontend/textbooks/algebra_9_ch4.html b/frontend/textbooks/algebra_9_ch4.html index 8f2fb18..4784466 100644 --- a/frontend/textbooks/algebra_9_ch4.html +++ b/frontend/textbooks/algebra_9_ch4.html @@ -1718,38 +1718,588 @@ function buildP17(){ } function buildP18(){ - const root = document.getElementById('p18-body'); - root.innerHTML = ` -
-
- ${ICONS.theory} - В разработке - § 18 + const box = document.getElementById('p18-body'); + let html = ''; + + html += makeCard('theory', 'Формула суммы $n$ членов', '18.1', ` +

Сумма первых $n$ членов геометрической прогрессии:

+

$$S_n = \\dfrac{b_1\\,(q^n - 1)}{q - 1},\\quad q \\ne 1.$$

+

Если $q = 1$ — все члены равны $b_1$, тогда $S_n = n \\cdot b_1$.

+

Также удобная форма (через $b_n$):

+

$$S_n = \\dfrac{b_n \\cdot q - b_1}{q - 1},\\quad q \\ne 1.$$

`); + + html += makeCard('rule', 'Вывод формулы', '18.2', ` +

Запишем сумму:

+

$$S_n = b_1 + b_1 q + b_1 q^2 + \\ldots + b_1 q^{n - 1}. \\quad (1)$$

+

Умножим обе части на $q$:

+

$$q\\,S_n = b_1 q + b_1 q^2 + b_1 q^3 + \\ldots + b_1 q^n. \\quad (2)$$

+

Вычтем $(1)$ из $(2)$ — почти все слагаемые сократятся:

+

$$q\\,S_n - S_n = b_1 q^n - b_1\\ \\Rightarrow\\ S_n(q - 1) = b_1(q^n - 1).$$

+

При $q \\ne 1$ делим на $q - 1$ и получаем формулу.

`); + + html += makeCard('example', 'Примеры применения', '18.3', ` +

а) Сумма первых 5 членов прогрессии $2, 4, 8, 16, 32$ ($b_1 = 2,\\ q = 2$):

+

$$S_5 = \\dfrac{2\\,(2^5 - 1)}{2 - 1} = 2 \\cdot 31 = \\mathbf{62}.$$

+

б) Сумма $1 + 3 + 9 + 27 + \\ldots + 3^{10}$ — это $b_1 = 1,\\ q = 3,\\ n = 11$:

+

$$S_{11} = \\dfrac{1 \\cdot (3^{11} - 1)}{3 - 1} = \\dfrac{177146}{2} = \\mathbf{88\\,573}.$$

+

в) Особый случай $q = -1$ для $b_1 = 1$: ряд $1, -1, 1, -1, \\ldots$ даёт $S_n = 0$ при чётном $n$ и $S_n = 1$ при нечётном.

`); + + /* INTERACTIVE 1 — конструктор суммы */ + html += `
+
ИНТЕРАКТИВ 1
Конструктор суммы $S_n$
+
Двигай $b_1$, $q$, $n$ — увидишь первые члены, подстановку в формулу и итог. Особый случай $q = 1$ обработан.
+
+ + + +
+
+
+
+
`; + + /* INTERACTIVE 2 — калькулятор S_n */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор $S_n$
+
Введи $b_1$, $q$, $n$ — получишь $q^n$ и полную подстановку в формулу.
+
+
+ $b_1$ = + $q$ = + $n$ =
-
-

Содержание параграфа «Сумма геом. прогрессии» будет добавлено в следующих обновлениях.

-

Раздел Phase 1.

-
-
` + secNav('p17', 'p19') + readButton('p18'); - renderMath(root); + +
+
+
`; + + /* INTERACTIVE 3 — сравни формулы */ + html += `
+
ИНТЕРАКТИВ 3
Сравни формулы: верно или ошибка?
+
Перед тобой утверждение. Реши, верное оно или содержит ошибку в применении формулы $S_n = \\dfrac{b_1(q^n - 1)}{q - 1}$.
+
Задача: 1 / 6 · Очки: 0
+
+
+ + +
+ +
`; + + /* INTERACTIVE 4 — тренажёр */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр на $S_n$
+
Вычисляй суммы по формуле $S_n = \\dfrac{b_1(q^n - 1)}{q - 1}$. Ответ — целое число.
+
Задача: 1 / 6 · Очки: 0
+
+
+ Ответ: + + +
+ +
`; + + box.innerHTML = html + secNav('p17', 'p19') + readButton('p18'); + renderMath(box); + + /* ===== IV1 wiring ===== */ + (function(){ + const b1Sl = document.getElementById('p18-iv1-b1'); + const qSl = document.getElementById('p18-iv1-q'); + const nSl = document.getElementById('p18-iv1-n'); + const bv = document.getElementById('p18-iv1-bv'); + const qv = document.getElementById('p18-iv1-qv'); + const nv = document.getElementById('p18-iv1-nv'); + const termsEl = document.getElementById('p18-iv1-terms'); + const fEl = document.getElementById('p18-iv1-formula'); + const outEl = document.getElementById('p18-iv1-out'); + let bumped = false; + + function fmtQ(q){ + if (Math.abs(q - 0.5) < 1e-9) return '\\dfrac{1}{2}'; + if (Math.abs(q + 0.5) < 1e-9) return '-\\dfrac{1}{2}'; + if (Math.abs(q - 1.5) < 1e-9) return '\\dfrac{3}{2}'; + if (Math.abs(q + 1.5) < 1e-9) return '-\\dfrac{3}{2}'; + return fmt(q); + } + + function redraw(){ + const b1 = +b1Sl.value, q = +qSl.value, n = +nSl.value; + bv.textContent = b1; qv.textContent = q; nv.textContent = n; + + // первые n членов + const terms = []; + for (let i = 0; i < n; i++) terms.push(b1 * Math.pow(q, i)); + const sum = terms.reduce((a,b)=>a+b, 0); + const termsStr = terms.map(t => fmt(+t.toFixed(4))).join('\\ +\\ '); + termsEl.innerHTML = 'Члены: $' + termsStr + '$'; + + if (Math.abs(q - 1) < 1e-9){ + fEl.innerHTML = 'Особый случай $q = 1$: $S_n = n \\cdot b_1 = ' + n + ' \\cdot ' + b1 + ' = \\mathbf{' + (n*b1) + '}$.'; + outEl.innerHTML = '$S_{' + n + '} = \\mathbf{' + (n*b1) + '}$'; + } else { + const qN = Math.pow(q, n); + fEl.innerHTML = '$S_{' + n + '} = \\dfrac{b_1(q^n - 1)}{q - 1} = \\dfrac{' + b1 + '\\,((' + fmtQ(q) + ')^{' + n + '} - 1)}{' + fmtQ(q) + ' - 1}$'; + outEl.innerHTML = '$q^n = ' + fmt(+qN.toFixed(4)) + ',\\quad S_{' + n + '} = \\mathbf{' + fmt(+sum.toFixed(4)) + '}$'; + } + renderMath(termsEl); renderMath(fEl); renderMath(outEl); + if (!bumped){ bumped = true; bumpProgress('p18', 15); addXp(10,'p18-iv1'); } + } + b1Sl.addEventListener('input', redraw); + qSl.addEventListener('input', redraw); + nSl.addEventListener('input', redraw); + redraw(); + })(); + + /* ===== IV2 wiring ===== */ + (function(){ + const out = document.getElementById('p18-iv2-out'); + let bumped = false; + document.getElementById('p18-iv2-go').addEventListener('click', ()=>{ + const b1 = +document.getElementById('p18-iv2-b1').value; + const q = +document.getElementById('p18-iv2-q').value; + const n = +document.getElementById('p18-iv2-n').value; + if (!Number.isInteger(n) || n < 1){ out.innerHTML = 'Число членов $n$ должно быть натуральным.'; renderMath(out); return; } + if (b1 === 0){ out.innerHTML = 'Должно быть $b_1 \\ne 0$.'; renderMath(out); return; } + if (q === 0){ out.innerHTML = 'Знаменатель $q$ должен быть $\\ne 0$.'; renderMath(out); return; } + if (Math.abs(q - 1) < 1e-9){ + out.innerHTML = '$q = 1$: $S_n = n \\cdot b_1 = ' + n + ' \\cdot ' + b1 + ' = \\mathbf{' + (n*b1) + '}$'; + renderMath(out); + } else { + const qN = Math.pow(q, n); + const S = b1 * (qN - 1) / (q - 1); + out.innerHTML = '$q^n = ' + fmt(q) + '^{' + n + '} = ' + fmt(+qN.toFixed(6)) + + '$
$S_n = \\dfrac{b_1(q^n - 1)}{q - 1} = \\dfrac{' + b1 + '\\,(' + fmt(+qN.toFixed(6)) + ' - 1)}{' + fmt(q) + ' - 1} = \\mathbf{' + fmt(+S.toFixed(6)) + '}$'; + renderMath(out); + } + if (!bumped){ bumped = true; bumpProgress('p18', 15); addXp(10,'p18-iv2'); } + }); + })(); + + /* ===== IV3 wiring ===== */ + (function(){ + const items = [ + { q:'$1 + 2 + 4 + 8 = \\dfrac{1 \\cdot (2^4 - 1)}{2 - 1} = 15$', + ans:true, hint:'$b_1 = 1,\\ q = 2,\\ n = 4$: $\\dfrac{16 - 1}{1} = 15$. Верно.' }, + { q:'$1 + 3 + 9 + 27 = \\dfrac{1 \\cdot (3^4 - 1)}{2} = 40$', + ans:true, hint:'$b_1 = 1,\\ q = 3,\\ n = 4$: $\\dfrac{81 - 1}{2} = 40$. Верно.' }, + { q:'Для $q \\ne 1$ верно $S_n = \\dfrac{b_1\\,q^n}{q - 1}$', + ans:false, hint:'Ошибка: в числителе должно быть $q^n - 1$, а не просто $q^n$.' }, + { q:'$5 + 5 + 5 + 5 + 5 = 5 \\cdot 5 = 25$ (при $q = 1$)', + ans:true, hint:'При $q = 1$ формула $S_n = n \\cdot b_1 = 5 \\cdot 5 = 25$. Верно.' }, + { q:'Для $q \\ne 1$ верно $S_3 = b_1 + b_1 q + b_1 q^2 = 3 b_1$', + ans:false, hint:'Сумма равна $3 b_1$ только при $q = 1$. В общем случае это $b_1(1 + q + q^2)$.' }, + { q:'$1 - 2 + 4 - 8 + 16 = \\dfrac{1 \\cdot ((-2)^5 - 1)}{-2 - 1} = \\dfrac{-33}{-3} = 11$', + ans:true, hint:'$b_1 = 1,\\ q = -2,\\ n = 5$: $(-2)^5 = -32$, $\\dfrac{-33}{-3} = 11$. Верно.' } + ]; + let i = 0, sc = 0; + const idxEl = document.getElementById('p18-iv3-idx'); + const scEl = document.getElementById('p18-iv3-sc'); + const qEl = document.getElementById('p18-iv3-q'); + const fb = document.getElementById('p18-iv3-fb'); + const yBtn = document.getElementById('p18-iv3-y'); + const nBtn = document.getElementById('p18-iv3-n'); + let bumped = false; + function render(){ + idxEl.textContent = Math.min(i+1, items.length); + scEl.textContent = sc; + if (i >= items.length){ + qEl.innerHTML = 'Готово! Результат: ' + sc + ' / ' + items.length; + yBtn.disabled = true; nBtn.disabled = true; + yBtn.style.opacity = .5; nBtn.style.opacity = .5; + if (!bumped){ bumped = true; bumpProgress('p18', 25); addXp(15,'p18-iv3'); } + return; + } + qEl.innerHTML = items[i].q; + fb.style.display = 'none'; + renderMath(qEl); + } + function answer(v){ + if (i >= items.length) return; + const it = items[i]; + const ok = (v === it.ans); + if (ok) sc++; + feedback(fb, ok, (ok?'✓ Верно. ':'✗ Неверно. ') + it.hint); + i++; + setTimeout(render, 1200); + } + yBtn.addEventListener('click', ()=>answer(true)); + nBtn.addEventListener('click', ()=>answer(false)); + render(); + })(); + + /* ===== IV4 wiring ===== */ + (function(){ + const items = [ + { q:'Найди $1 + 2 + 4 + 8 + 16$.', ans: 31 }, + { q:'$b_1 = 3,\\ q = 2$. Найти $S_5$.', ans: 93 }, + { q:'Найди $1 + 3 + 9 + 27$.', ans: 40 }, + { q:'$b_1 = 4,\\ q = -1$. Найти $S_5$.', ans: 4 }, + { q:'$b_1 = 8,\\ q = \\dfrac{1}{2}$. Найти $S_4$.', ans: 15 }, + { q:'Геом. прогрессия $1, 4, 16, \\ldots, 256$. Найти сумму всех её членов.', ans: 341 } + ]; + let i = 0, sc = 0; + const idxEl = document.getElementById('p18-iv4-idx'); + const scEl = document.getElementById('p18-iv4-sc'); + const qEl = document.getElementById('p18-iv4-q'); + const inp = document.getElementById('p18-iv4-ans'); + const btn = document.getElementById('p18-iv4-go'); + const fb = document.getElementById('p18-iv4-fb'); + let bumped = false; + function render(){ + idxEl.textContent = Math.min(i+1, items.length); + scEl.textContent = sc; + if (i >= items.length){ + qEl.innerHTML = 'Готово! Результат: ' + sc + ' / ' + items.length; + inp.disabled = true; btn.disabled = true; + inp.style.opacity = .5; btn.style.opacity = .5; + if (!bumped){ bumped = true; bumpProgress('p18', 25); addXp(15,'p18-iv4'); } + return; + } + qEl.innerHTML = items[i].q; + inp.value = ''; fb.style.display = 'none'; + renderMath(qEl); + } + btn.addEventListener('click', ()=>{ + if (i >= items.length) return; + const v = +inp.value; + const it = items[i]; + const ok = (v === it.ans); + if (ok) sc++; + feedback(fb, ok, ok ? '✓ Верно: $'+it.ans+'$' : '✗ Неверно. Правильный ответ: $'+it.ans+'$'); + i++; + setTimeout(render, 1100); + }); + inp.addEventListener('keydown', e=>{ if(e.key==='Enter'){ e.preventDefault(); btn.click(); } }); + render(); + })(); + wireReadBtn('p18'); } function buildP19(){ - const root = document.getElementById('p19-body'); - root.innerHTML = ` -
-
- ${ICONS.theory} - В разработке - § 19 + const box = document.getElementById('p19-body'); + let html = ''; + + html += makeCard('theory', 'Когда прогрессия бесконечно убывающая', '19.1', ` +

Геометрическая прогрессия называется бесконечно убывающей, если её знаменатель удовлетворяет:

+

$$|q| < 1\\quad\\text{и}\\quad q \\ne 0.$$

+

При $|q| < 1$ члены $b_n = b_1 q^{n - 1}$ по модулю стремятся к нулю с ростом $n$.

+

Пример. Прогрессия $1, \\dfrac{1}{2}, \\dfrac{1}{4}, \\dfrac{1}{8}, \\ldots$ имеет $q = \\dfrac{1}{2}$, $|q| < 1$ — бесконечно убывающая.

`); + + html += makeCard('rule', 'Формула суммы $S$', '19.2', ` +

Сумма всех членов бесконечно убывающей геом. прогрессии:

+

$$S = \\dfrac{b_1}{1 - q},\\quad |q| < 1.$$

+

Откуда это? Это предел $S_n$ при $n \\to \\infty$. Действительно,

+

$$S_n = \\dfrac{b_1\\,(q^n - 1)}{q - 1}.$$

+

При $|q| < 1$ имеем $q^n \\to 0$, поэтому

+

$$S = \\lim_{n \\to \\infty} S_n = \\dfrac{b_1 \\cdot (0 - 1)}{q - 1} = \\dfrac{-b_1}{q - 1} = \\dfrac{b_1}{1 - q}.$$

`); + + html += makeCard('example', 'Примеры', '19.3', ` +

а) $1 + \\dfrac{1}{2} + \\dfrac{1}{4} + \\dfrac{1}{8} + \\ldots = \\dfrac{1}{1 - \\tfrac{1}{2}} = \\mathbf{2}.$

+

б) $1 - \\dfrac{1}{3} + \\dfrac{1}{9} - \\dfrac{1}{27} + \\ldots = \\dfrac{1}{1 - (-\\tfrac{1}{3})} = \\dfrac{1}{\\tfrac{4}{3}} = \\mathbf{\\dfrac{3}{4}}.$

+

в) Знаменитое равенство $0{,}(9) = 1$. Действительно:

+

$$0{,}999\\ldots = 0{,}9 + 0{,}09 + 0{,}009 + \\ldots = \\dfrac{0{,}9}{1 - 0{,}1} = \\dfrac{0{,}9}{0{,}9} = \\mathbf{1}.$$

+

г) Превращение периодической дроби в обыкновенную:

+

$$0{,}(3) = 0{,}3 + 0{,}03 + 0{,}003 + \\ldots = \\dfrac{0{,}3}{1 - 0{,}1} = \\dfrac{0{,}3}{0{,}9} = \\mathbf{\\dfrac{1}{3}}.$$

`); + + /* INTERACTIVE 1 — визуализация сходимости */ + html += `
+
ИНТЕРАКТИВ 1
Визуализация сходимости
+
Двигай $b_1$ и $q$ (при $|q| < 1$). На диаграмме — столбики первых 15 членов и нарастающая сумма, которая стремится к $S = \\dfrac{b_1}{1 - q}$.
+
+ + +
+
+ +
+
+
+
`; + + /* INTERACTIVE 2 — калькулятор S */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор $S = \\dfrac{b_1}{1 - q}$
+
$q$ задаётся обыкновенной дробью — введи числитель и знаменатель отдельно.
+
+
+ $b_1$ = + $q$ числитель = + $q$ знаменатель =
-
-

Содержание параграфа «Бесконечно убывающая» будет добавлено в следующих обновлениях.

-

Раздел Phase 1.

-
-
` + secNav('p18', 'final4') + readButton('p19'); - renderMath(root); + +
+
+
`; + + /* INTERACTIVE 3 — можно ли применить формулу */ + html += `
+
ИНТЕРАКТИВ 3
Можно ли применить формулу $\\dfrac{b_1}{1 - q}$?
+
Формула работает только при $|q| < 1$ и $q \\ne 0$. Реши, подходит ли данная прогрессия.
+
Задача: 1 / 6 · Очки: 0
+
+
+ + +
+ +
`; + + /* INTERACTIVE 4 — тренажёр */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр сумм $S = \\dfrac{b_1}{1 - q}$
+
В каждой задаче указано, что вводить (целое значение, или числитель / знаменатель ответа).
+
Задача: 1 / 6 · Очки: 0
+
+
+ Ответ: + + +
+ +
`; + + box.innerHTML = html + secNav('p18', 'final4') + readButton('p19'); + renderMath(box); + + /* ===== IV1 wiring — визуализация ===== */ + (function(){ + const svg = document.getElementById('p19-iv1-svg'); + const b1Sl = document.getElementById('p19-iv1-b1'); + const qSl = document.getElementById('p19-iv1-q'); + const bv = document.getElementById('p19-iv1-bv'); + const qv = document.getElementById('p19-iv1-qv'); + const fEl = document.getElementById('p19-iv1-formula'); + const outEl = document.getElementById('p19-iv1-out'); + let bumped = false; + + function redraw(){ + const b1 = +b1Sl.value, q = +qSl.value; + bv.textContent = b1; qv.textContent = q.toFixed(2); + + const N = 15; + const terms = []; + const partial = []; + let s = 0; + for (let i = 0; i < N; i++){ + const t = b1 * Math.pow(q, i); + terms.push(t); s += t; partial.push(s); + } + const Sinf = (Math.abs(q) < 1 - 1e-9) ? b1 / (1 - q) : NaN; + + // SVG: верх — столбики членов, низ — частичные суммы + const W = 480, H = 280, pad = 22; + const barAreaH = 130; + const partAreaTop = 160; + const partAreaH = 100; + const ux = (W - 2*pad) / N; + + // вертикальный масштаб для членов + const tmax = Math.max(...terms.map(Math.abs), 1e-6); + const tScale = (barAreaH / 2 - 6) / tmax; + const tMid = pad + barAreaH / 2; + + // масштаб для частичных + const allP = partial.concat([Sinf||0, 0]); + let pMin = Math.min(...allP), pMax = Math.max(...allP); + if (pMax === pMin){ pMin -= 1; pMax += 1; } + const padP = (pMax - pMin) * 0.15; + pMin -= padP; pMax += padP; + const pScale = (partAreaH - 12) / (pMax - pMin); + const pToY = v => partAreaTop + 6 + (pMax - v) * pScale; + + let g = ''; + // фон областей + g += ''; + g += ''; + // средняя линия для членов (ось 0) + g += ''; + g += 'Члены $b_n$'; + g += 'Частичные суммы $S_n$'; + + // столбики членов + const barW = ux * 0.7; + for (let i = 0; i < N; i++){ + const x = pad + ux * (i + 0.15); + const h = Math.abs(terms[i]) * tScale; + const y = terms[i] >= 0 ? tMid - h : tMid; + const color = terms[i] >= 0 ? '#0891b2' : '#ef4444'; + g += ''; + } + + // линия Sinf + if (isFinite(Sinf)){ + const ySinf = pToY(Sinf); + g += ''; + g += '$S = '+fmt(+Sinf.toFixed(4))+'$'; + } + // линия 0 в нижней области + const yZero = pToY(0); + if (yZero >= partAreaTop && yZero <= partAreaTop + partAreaH){ + g += ''; + } + // точки и ломаная частичных сумм + let path = ''; + for (let i = 0; i < N; i++){ + const x = pad + ux * (i + 0.5); + const y = pToY(partial[i]); + path += (i === 0 ? 'M' : ' L') + x.toFixed(1) + ',' + y.toFixed(1); + } + g += ''; + for (let i = 0; i < N; i++){ + const x = pad + ux * (i + 0.5); + const y = pToY(partial[i]); + g += ''; + } + + svg.innerHTML = g; + + // формула + if (isFinite(Sinf)){ + fEl.innerHTML = '$S = \\dfrac{b_1}{1 - q} = \\dfrac{' + b1 + '}{1 - (' + q.toFixed(2) + ')} = \\mathbf{' + fmt(+Sinf.toFixed(4)) + '}$'; + // частичные S_1..S_10 + const ps = partial.slice(0, 10).map((s,i)=>'$S_{'+(i+1)+'}\\!=\\!'+fmt(+s.toFixed(3))+'$').join(',\\ '); + outEl.innerHTML = 'Частичные суммы: ' + ps + ' — стремятся к $S$.'; + } else { + fEl.innerHTML = '$|q| \\ge 1$: прогрессия не является бесконечно убывающей.'; + outEl.innerHTML = 'Частичные суммы расходятся — формула $\\dfrac{b_1}{1 - q}$ не применима.'; + } + renderMath(fEl); renderMath(outEl); + if (!bumped){ bumped = true; bumpProgress('p19', 15); addXp(10,'p19-iv1'); } + } + b1Sl.addEventListener('input', redraw); + qSl.addEventListener('input', redraw); + redraw(); + })(); + + /* ===== IV2 wiring ===== */ + (function(){ + const out = document.getElementById('p19-iv2-out'); + let bumped = false; + document.getElementById('p19-iv2-go').addEventListener('click', ()=>{ + const b1 = +document.getElementById('p19-iv2-b1').value; + const qn = +document.getElementById('p19-iv2-qn').value; + const qd = +document.getElementById('p19-iv2-qd').value; + if (qd === 0){ out.innerHTML = 'Знаменатель $q$ не может быть нулём.'; renderMath(out); return; } + if (b1 === 0){ out.innerHTML = 'Должно быть $b_1 \\ne 0$.'; renderMath(out); return; } + const q = qn / qd; + if (q === 0){ out.innerHTML = '$q$ должен быть отличен от $0$.'; renderMath(out); return; } + if (Math.abs(q) >= 1){ + out.innerHTML = '$q = \\dfrac{'+qn+'}{'+qd+'} = '+fmt(q)+'$. $|q| \\ge 1$ — прогрессия не бесконечно убывающая!'; + renderMath(out); return; + } + // S = b1 / (1 - q) = b1 * qd / (qd - qn) + const num = b1 * qd; + const den = qd - qn; + const g = gcd(num, den); + const sNum = num / g, sDen = den / g; + // знак в числитель + let nn = sNum, dd = sDen; + if (dd < 0){ nn = -nn; dd = -dd; } + const S = b1 / (1 - q); + let frac; + if (dd === 1) frac = '' + nn; + else frac = '\\dfrac{' + nn + '}{' + dd + '}'; + out.innerHTML = '$q = \\dfrac{'+qn+'}{'+qd+'},\\ |q| < 1$  ✓
$S = \\dfrac{b_1}{1 - q} = \\dfrac{'+b1+'}{1 - \\tfrac{'+qn+'}{'+qd+'}} = \\dfrac{'+b1+' \\cdot '+qd+'}{'+qd+' - ('+qn+')} = \\mathbf{'+frac+'} \\approx '+fmt(+S.toFixed(4))+'$'; + renderMath(out); + if (!bumped){ bumped = true; bumpProgress('p19', 15); addXp(10,'p19-iv2'); } + }); + })(); + + /* ===== IV3 wiring ===== */ + (function(){ + const items = [ + { q:'$b_1 = 1,\\ q = \\dfrac{1}{2}$', ans:true, hint:'$|q| = \\tfrac{1}{2} < 1$ — формула применима.' }, + { q:'$b_1 = 1,\\ q = 2$', ans:false, hint:'$|q| = 2 > 1$ — прогрессия расходится, формула неприменима.' }, + { q:'$b_1 = 5,\\ q = -\\dfrac{1}{3}$', ans:true, hint:'$|q| = \\tfrac{1}{3} < 1$ — формула применима.' }, + { q:'$b_1 = 100,\\ q = 0{,}99$', ans:true, hint:'$|q| = 0{,}99 < 1$ — формула применима (сходимость медленная, но есть).' }, + { q:'$b_1 = 1,\\ q = -1$', ans:false, hint:'$|q| = 1$ — граница, формула неприменима ($1 - 1 + 1 - 1 + \\ldots$ не сходится).' }, + { q:'$b_1 = 1,\\ q = 1$', ans:false, hint:'$|q| = 1$ — это вообще не убывающая прогрессия ($1 + 1 + 1 + \\ldots = \\infty$).' } + ]; + let i = 0, sc = 0; + const idxEl = document.getElementById('p19-iv3-idx'); + const scEl = document.getElementById('p19-iv3-sc'); + const qEl = document.getElementById('p19-iv3-q'); + const fb = document.getElementById('p19-iv3-fb'); + const yBtn = document.getElementById('p19-iv3-y'); + const nBtn = document.getElementById('p19-iv3-n'); + let bumped = false; + function render(){ + idxEl.textContent = Math.min(i+1, items.length); + scEl.textContent = sc; + if (i >= items.length){ + qEl.innerHTML = 'Готово! Результат: ' + sc + ' / ' + items.length; + yBtn.disabled = true; nBtn.disabled = true; + yBtn.style.opacity = .5; nBtn.style.opacity = .5; + if (!bumped){ bumped = true; bumpProgress('p19', 25); addXp(15,'p19-iv3'); } + return; + } + qEl.innerHTML = items[i].q; + fb.style.display = 'none'; + renderMath(qEl); + } + function answer(v){ + if (i >= items.length) return; + const it = items[i]; + const ok = (v === it.ans); + if (ok) sc++; + feedback(fb, ok, (ok?'✓ Верно. ':'✗ Неверно. ') + it.hint); + i++; + setTimeout(render, 1200); + } + yBtn.addEventListener('click', ()=>answer(true)); + nBtn.addEventListener('click', ()=>answer(false)); + render(); + })(); + + /* ===== IV4 wiring ===== */ + (function(){ + const items = [ + { q:'$1 + \\dfrac{1}{2} + \\dfrac{1}{4} + \\ldots = \\ ?$ Введи целое значение $S$.', ans: 2, expl:'$S = \\dfrac{1}{1 - 1/2} = 2$.' }, + { q:'$4 + 2 + 1 + \\dfrac{1}{2} + \\ldots = \\ ?$ Введи целое значение $S$.', ans: 8, expl:'$b_1 = 4,\\ q = \\tfrac{1}{2}$: $S = \\dfrac{4}{1 - 1/2} = 8$.' }, + { q:'$1 - \\dfrac{1}{2} + \\dfrac{1}{4} - \\ldots = \\dfrac{2}{?}$ Введи знаменатель.', ans: 3, expl:'$S = \\dfrac{1}{1 + 1/2} = \\dfrac{2}{3}$.' }, + { q:'$0{,}(6) = 0{,}666\\ldots = \\dfrac{2}{?}$ Введи знаменатель.', ans: 3, expl:'$S = \\dfrac{0{,}6}{1 - 0{,}1} = \\dfrac{0{,}6}{0{,}9} = \\dfrac{2}{3}$.' }, + { q:'$9 + 3 + 1 + \\dfrac{1}{3} + \\ldots = \\dfrac{?}{2}$ Введи числитель.', ans: 27, expl:'$S = \\dfrac{9}{1 - 1/3} = \\dfrac{9 \\cdot 3}{2} = \\dfrac{27}{2}$.' }, + { q:'$0{,}(12) = 0{,}1212\\ldots = \\dfrac{4}{?}$ Введи знаменатель.', ans: 33, expl:'$S = \\dfrac{0{,}12}{1 - 0{,}01} = \\dfrac{12}{99} = \\dfrac{4}{33}$.' } + ]; + let i = 0, sc = 0; + const idxEl = document.getElementById('p19-iv4-idx'); + const scEl = document.getElementById('p19-iv4-sc'); + const qEl = document.getElementById('p19-iv4-q'); + const inp = document.getElementById('p19-iv4-ans'); + const btn = document.getElementById('p19-iv4-go'); + const fb = document.getElementById('p19-iv4-fb'); + let bumped = false; + function render(){ + idxEl.textContent = Math.min(i+1, items.length); + scEl.textContent = sc; + if (i >= items.length){ + qEl.innerHTML = 'Готово! Результат: ' + sc + ' / ' + items.length; + inp.disabled = true; btn.disabled = true; + inp.style.opacity = .5; btn.style.opacity = .5; + if (!bumped){ bumped = true; bumpProgress('p19', 25); addXp(15,'p19-iv4'); } + return; + } + qEl.innerHTML = items[i].q; + inp.value = ''; fb.style.display = 'none'; + renderMath(qEl); + } + btn.addEventListener('click', ()=>{ + if (i >= items.length) return; + const v = +inp.value; + const it = items[i]; + const ok = (v === it.ans); + if (ok) sc++; + feedback(fb, ok, (ok ? '✓ Верно: $'+it.ans+'$. ' : '✗ Неверно. Правильный ответ: $'+it.ans+'$. ') + it.expl); + i++; + setTimeout(render, 1300); + }); + inp.addEventListener('keydown', e=>{ if(e.key==='Enter'){ e.preventDefault(); btn.click(); } }); + render(); + })(); + wireReadBtn('p19'); }