feat(alg9 ch4 wave2): §16 «Сумма арифм.» + §17 «Геом. прогрессия»
This commit is contained in:
@@ -1120,38 +1120,600 @@ function buildP15(){
|
||||
}
|
||||
|
||||
function buildP16(){
|
||||
const root = document.getElementById('p16-body');
|
||||
root.innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<span class="card-icon theory">${ICONS.theory}</span>
|
||||
<span class="card-title">В разработке</span>
|
||||
<span class="card-num">§ 16</span>
|
||||
const box = document.getElementById('p16-body');
|
||||
let html = '';
|
||||
|
||||
html += makeCard('theory', 'Формула суммы (через крайние члены)', '16.1', `
|
||||
<p>Сумма $n$ первых членов арифметической прогрессии равна <b>полусумме первого и последнего</b> члена, умноженной на число членов:</p>
|
||||
<p>$$S_n = \\dfrac{a_1 + a_n}{2} \\cdot n.$$</p>
|
||||
<p>Удобно применять, когда известны <b>$a_1$, $a_n$ и $n$</b> (или их легко найти).</p>`);
|
||||
|
||||
html += makeCard('rule', 'Формула суммы (через $a_1$ и $d$)', '16.2', `
|
||||
<p>Подставив $a_n = a_1 + (n - 1) d$ в первую формулу, получим:</p>
|
||||
<p>$$S_n = \\dfrac{2 a_1 + (n - 1) d}{2} \\cdot n.$$</p>
|
||||
<p>Эта формула удобна, когда заданы <b>$a_1$, $d$ и $n$</b>. Обе формулы эквивалентны и дают один и тот же результат.</p>`);
|
||||
|
||||
html += makeCard('example', 'Идея вывода (Гаусс) и примеры', '16.3', `
|
||||
<p><b>Идея вывода.</b> Пусть $S = 1 + 2 + 3 + \\ldots + 100$. Сложим пары крайних членов:
|
||||
$(1 + 100) + (2 + 99) + \\ldots + (50 + 51)$. Каждая пара даёт $101$, пар $50$, поэтому
|
||||
$S = 50 \\cdot 101 = \\mathbf{5050}$.</p>
|
||||
<p>Аналогично для арифм. прогрессии: пар $n/2$, каждая равна $a_1 + a_n$, итого $S_n = \\dfrac{(a_1 + a_n) \\cdot n}{2}$.</p>
|
||||
<p><b>а)</b> Сумма первых $20$ членов прогрессии $3, 7, 11, \\ldots$: $a_1 = 3$, $d = 4$, $a_{20} = 3 + 19 \\cdot 4 = 79$. Тогда $S_{20} = \\dfrac{3 + 79}{2} \\cdot 20 = \\mathbf{820}.$</p>
|
||||
<p><b>б)</b> Сумма первых $100$ натуральных чисел: $S = \\dfrac{1 + 100}{2} \\cdot 100 = \\mathbf{5050}.$</p>`);
|
||||
|
||||
/* INTERACTIVE 1 — конструктор суммы (Гаусс-пары) */
|
||||
html += `<div class="wg" id="p16-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Конструктор суммы (приём Гаусса)</div></div>
|
||||
<div class="wg-help">Двигай ползунки $a_1$, $d$, $n$. Будут показаны все $n$ членов и подсвечены пары крайних — каждая пара даёт одно и то же число $a_1 + a_n$.</div>
|
||||
<div class="sliders">
|
||||
<label>$a_1$ =<b id="p16-iv1-av">0</b><input type="range" id="p16-iv1-a1" min="-10" max="10" step="1" value="3"></label>
|
||||
<label>$d$ =<b id="p16-iv1-dv">0</b><input type="range" id="p16-iv1-d" min="-5" max="5" step="1" value="4"></label>
|
||||
<label>$n$ =<b id="p16-iv1-nv">0</b><input type="range" id="p16-iv1-n" min="2" max="20" step="1" value="8"></label>
|
||||
</div>
|
||||
<div id="p16-iv1-terms" style="padding:12px;background:var(--card);border-radius:10px;margin-bottom:10px;font-family:'JetBrains Mono',monospace;font-size:.95rem;line-height:1.9;text-align:center;overflow-x:auto"></div>
|
||||
<div id="p16-iv1-pairs" style="padding:10px 12px;background:var(--sec-acc-soft);border-radius:9px;margin-bottom:10px;font-size:.92rem;text-align:center"></div>
|
||||
<div id="p16-iv1-formula" style="padding:12px;background:var(--card);border-radius:10px;font-size:1rem;text-align:center"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — калькулятор суммы */
|
||||
html += `<div class="wg" id="p16-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор суммы $S_n$</div></div>
|
||||
<div class="wg-help">Введи $a_1$, $d$, $n$ — получишь $a_n$ и $S_n$ с подстановкой.</div>
|
||||
<div style="background:var(--card);border-radius:11px;padding:14px;max-width:480px;margin:0 auto">
|
||||
<div style="display:grid;grid-template-columns:auto 1fr;gap:8px 10px;align-items:center;margin-bottom:10px">
|
||||
<span>$a_1$ =</span><input type="number" id="p16-iv2-a1" class="tinp" value="3" step="1">
|
||||
<span>$d$ =</span><input type="number" id="p16-iv2-d" class="tinp" value="4" step="1">
|
||||
<span>$n$ =</span><input type="number" id="p16-iv2-n" class="tinp" value="20" step="1" min="1">
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Содержание параграфа <b>«Сумма арифм. прогрессии»</b> будет добавлено в следующих обновлениях.</p>
|
||||
<p style="color:var(--muted);font-size:.9rem">Раздел Phase 1.</p>
|
||||
</div>
|
||||
</div>` + secNav('p15', 'p17') + readButton('p16');
|
||||
renderMath(root);
|
||||
<button class="btn primary" id="p16-iv2-go" style="width:100%">Вычислить $S_n$</button>
|
||||
<div id="p16-iv2-out" style="margin-top:10px;padding:10px 12px;background:var(--sec-acc-soft);border-radius:8px;font-size:.95rem;min-height:36px;line-height:1.7"></div>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — найди ошибку в формуле */
|
||||
html += `<div class="wg" id="p16-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Найди ошибку в формуле</div></div>
|
||||
<div class="wg-help">Перед тобой — утверждение. Если оно верное, жми «Верно»; если есть ошибка — «Ошибка».</div>
|
||||
<div class="score-display">Задача: <b id="p16-iv3-idx">1</b> / 6 · Очки: <b id="p16-iv3-sc">0</b></div>
|
||||
<div id="p16-iv3-q" style="text-align:center;font-size:1.05rem;padding:14px;background:var(--card);border-radius:9px;margin-bottom:12px;min-height:70px"></div>
|
||||
<div class="actions" style="justify-content:center">
|
||||
<button class="btn primary" id="p16-iv3-y">Верно</button>
|
||||
<button class="btn" id="p16-iv3-n">Ошибка</button>
|
||||
</div>
|
||||
<div class="feedback" id="p16-iv3-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — тренажёр сумм */
|
||||
html += `<div class="wg" id="p16-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр сумм</div></div>
|
||||
<div class="wg-help">Применяй $S_n = \\dfrac{a_1 + a_n}{2} \\cdot n$ или $S_n = \\dfrac{2 a_1 + (n - 1) d}{2} \\cdot n$. Ответ — целое число.</div>
|
||||
<div class="score-display">Задача: <b id="p16-iv4-idx">1</b> / 6 · Очки: <b id="p16-iv4-sc">0</b></div>
|
||||
<div id="p16-iv4-q" style="text-align:center;font-size:1.05rem;padding:14px;background:var(--card);border-radius:9px;margin-bottom:12px;min-height:60px"></div>
|
||||
<div class="actions" style="justify-content:center;align-items:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">Ответ:</span>
|
||||
<input type="number" id="p16-iv4-ans" class="tinp" style="width:140px;text-align:center" step="1">
|
||||
<button class="btn primary" id="p16-iv4-go">Проверить</button>
|
||||
</div>
|
||||
<div class="feedback" id="p16-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
box.innerHTML = html + secNav('p15', 'p17') + readButton('p16');
|
||||
renderMath(box);
|
||||
|
||||
/* ===== IV1 wiring ===== */
|
||||
(function(){
|
||||
const a1Sl = document.getElementById('p16-iv1-a1');
|
||||
const dSl = document.getElementById('p16-iv1-d');
|
||||
const nSl = document.getElementById('p16-iv1-n');
|
||||
const av = document.getElementById('p16-iv1-av');
|
||||
const dv = document.getElementById('p16-iv1-dv');
|
||||
const nv = document.getElementById('p16-iv1-nv');
|
||||
const termsEl = document.getElementById('p16-iv1-terms');
|
||||
const pairsEl = document.getElementById('p16-iv1-pairs');
|
||||
const formEl = document.getElementById('p16-iv1-formula');
|
||||
const PAIR_COLORS = ['#ef4444','#0891b2','#16a34a','#a855f7','#f59e0b','#ec4899','#6366f1','#14b8a6','#f97316','#84cc16'];
|
||||
let bumped = false;
|
||||
|
||||
function redraw(){
|
||||
const a1 = +a1Sl.value, d = +dSl.value, n = +nSl.value;
|
||||
av.textContent = a1; dv.textContent = d; nv.textContent = n;
|
||||
|
||||
// массив членов
|
||||
const arr = [];
|
||||
for (let i=0;i<n;i++) arr.push(a1 + i*d);
|
||||
const an = arr[n-1];
|
||||
|
||||
// раскраска пар: i и n-1-i получают один цвет, средний (если n нечётно) — серый
|
||||
const colors = new Array(n).fill('#94a3b8');
|
||||
const halfPairs = Math.floor(n/2);
|
||||
for (let p=0;p<halfPairs;p++){
|
||||
const c = PAIR_COLORS[p % PAIR_COLORS.length];
|
||||
colors[p] = c;
|
||||
colors[n-1-p] = c;
|
||||
}
|
||||
|
||||
// отрисовка членов с цветами
|
||||
const parts = arr.map((v,i)=>'<span style="display:inline-block;padding:3px 9px;margin:2px;border-radius:7px;background:'+colors[i]+'15;color:'+colors[i]+';font-weight:700;border:1.5px solid '+colors[i]+'55">'+v+'</span>');
|
||||
termsEl.innerHTML = parts.join(' ');
|
||||
|
||||
// описание пар
|
||||
const pairSum = a1 + an;
|
||||
let pairsTxt = '';
|
||||
if (halfPairs > 0){
|
||||
const pairsList = [];
|
||||
for (let p=0;p<Math.min(halfPairs,3);p++){
|
||||
pairsList.push('('+arr[p]+'\\, +\\, '+arr[n-1-p]+')');
|
||||
}
|
||||
if (halfPairs > 3) pairsList.push('\\ldots');
|
||||
pairsTxt = '<b>Пары:</b> $' + pairsList.join('\\, +\\, ') + ' = ' + halfPairs + ' \\cdot ' + pairSum + ' = ' + (halfPairs*pairSum) + '$';
|
||||
if (n % 2 === 1){
|
||||
const mid = arr[(n-1)/2];
|
||||
pairsTxt += ' + <span style="color:#64748b">средний $' + mid + '$</span>';
|
||||
}
|
||||
} else {
|
||||
pairsTxt = '<b>n = 1</b>: $S_1 = a_1 = ' + a1 + '$';
|
||||
}
|
||||
pairsEl.innerHTML = pairsTxt;
|
||||
|
||||
// итог
|
||||
const Sn = (a1 + an) * n / 2;
|
||||
const dPart = (d>=0 ? '+ ' + d : '- ' + (-d));
|
||||
formEl.innerHTML = '$a_{'+n+'} = '+a1+' '+dPart+' \\cdot ('+n+' - 1) = '+an+'$<br>'+
|
||||
'$S_{'+n+'} = \\dfrac{'+a1+' + '+an+'}{2} \\cdot '+n+' = \\mathbf{'+Sn+'}$';
|
||||
|
||||
renderMath(pairsEl); renderMath(formEl);
|
||||
if (!bumped){ bumped = true; bumpProgress('p16', 15); addXp(10,'p16-iv1'); }
|
||||
}
|
||||
a1Sl.addEventListener('input', redraw);
|
||||
dSl.addEventListener('input', redraw);
|
||||
nSl.addEventListener('input', redraw);
|
||||
redraw();
|
||||
})();
|
||||
|
||||
/* ===== IV2 wiring ===== */
|
||||
(function(){
|
||||
const out = document.getElementById('p16-iv2-out');
|
||||
let bumped = false;
|
||||
document.getElementById('p16-iv2-go').addEventListener('click', ()=>{
|
||||
const a1 = +document.getElementById('p16-iv2-a1').value;
|
||||
const d = +document.getElementById('p16-iv2-d').value;
|
||||
const n = +document.getElementById('p16-iv2-n').value;
|
||||
if (!Number.isInteger(n) || n < 1){ out.innerHTML = 'Номер $n$ должен быть натуральным.'; renderMath(out); return; }
|
||||
const an = a1 + (n - 1) * d;
|
||||
const Sn = (a1 + an) * n / 2;
|
||||
const dPart = (d>=0 ? '+ ' + d : '- ' + (-d));
|
||||
out.innerHTML =
|
||||
'$a_{'+n+'} = '+a1+' '+dPart+' \\cdot ('+n+' - 1) = '+fmt(an)+'$<br>'+
|
||||
'$S_{'+n+'} = \\dfrac{'+a1+' + '+fmt(an)+'}{2} \\cdot '+n+' = \\mathbf{'+fmt(Sn)+'}$';
|
||||
renderMath(out);
|
||||
if (!bumped){ bumped = true; bumpProgress('p16', 15); addXp(10,'p16-iv2'); }
|
||||
});
|
||||
})();
|
||||
|
||||
/* ===== IV3 wiring ===== */
|
||||
(function(){
|
||||
const items = [
|
||||
{ q:'Для прогрессии $1, 3, 5, 7, 9$: $S_5 = \\dfrac{1 + 9}{2} \\cdot 5 = 25$.', ans:true, hint:'$\\dfrac{10}{2} \\cdot 5 = 25$.' },
|
||||
{ q:'$S_n = a_1 + (n - 1) d$.', ans:false, hint:'Это формула $a_n$, а не суммы. У суммы есть множитель $n/2$.' },
|
||||
{ q:'$S_n = \\dfrac{a_1 + a_n}{2} \\cdot n$.', ans:true, hint:'Классическая формула суммы через крайние члены.' },
|
||||
{ q:'Для $1, 3, 5, \\ldots, 19$ (10 членов): $S_{10} = \\dfrac{1 + 19}{2} \\cdot 10 = 100$.', ans:true, hint:'$\\dfrac{20}{2} \\cdot 10 = 100$.' },
|
||||
{ q:'$S_n = n \\cdot a_1 + d$.', ans:false, hint:'Слагаемых с $d$ должно быть много, а здесь только одно. Это не сумма.' },
|
||||
{ q:'Сумма первых $50$ натуральных чисел: $\\dfrac{50 \\cdot 51}{2} = 1275$.', ans:true, hint:'$S = \\dfrac{1 + 50}{2} \\cdot 50 = 1275$.' }
|
||||
];
|
||||
let i = 0, sc = 0;
|
||||
const idxEl = document.getElementById('p16-iv3-idx');
|
||||
const scEl = document.getElementById('p16-iv3-sc');
|
||||
const qEl = document.getElementById('p16-iv3-q');
|
||||
const fb = document.getElementById('p16-iv3-fb');
|
||||
const yBtn = document.getElementById('p16-iv3-y');
|
||||
const nBtn = document.getElementById('p16-iv3-n');
|
||||
let bumped = false;
|
||||
function render(){
|
||||
idxEl.textContent = Math.min(i+1, items.length);
|
||||
scEl.textContent = sc;
|
||||
if (i >= items.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + sc + ' / ' + items.length;
|
||||
yBtn.disabled = true; nBtn.disabled = true;
|
||||
yBtn.style.opacity = .5; nBtn.style.opacity = .5;
|
||||
if (!bumped){ bumped = true; bumpProgress('p16', 25); addXp(15,'p16-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, 1100);
|
||||
}
|
||||
yBtn.addEventListener('click', ()=>answer(true));
|
||||
nBtn.addEventListener('click', ()=>answer(false));
|
||||
render();
|
||||
})();
|
||||
|
||||
/* ===== IV4 wiring ===== */
|
||||
(function(){
|
||||
const items = [
|
||||
{ q:'Сумма первых 10 нечётных чисел: $1 + 3 + 5 + \\ldots + 19 = ?$', ans: 100 },
|
||||
{ q:'$a_1 = 5,\\ d = 2,\\ n = 6$. Найти $S_6$.', ans: 60 },
|
||||
{ q:'$a_1 = -3,\\ d = 4,\\ n = 10$. Найти $S_{10}$.', ans: 150 },
|
||||
{ q:'Сумма первых $100$ натуральных чисел.', ans: 5050 },
|
||||
{ q:'$a_1 = 2,\\ a_{20} = 40$. Найти $S_{20}$.', ans: 420 },
|
||||
{ q:'Прогрессия $7, 11, 15, \\ldots, 47$. Найти сумму всех её членов.', ans: 297 }
|
||||
];
|
||||
let i = 0, sc = 0;
|
||||
const idxEl = document.getElementById('p16-iv4-idx');
|
||||
const scEl = document.getElementById('p16-iv4-sc');
|
||||
const qEl = document.getElementById('p16-iv4-q');
|
||||
const inp = document.getElementById('p16-iv4-ans');
|
||||
const btn = document.getElementById('p16-iv4-go');
|
||||
const fb = document.getElementById('p16-iv4-fb');
|
||||
let bumped = false;
|
||||
function render(){
|
||||
idxEl.textContent = Math.min(i+1, items.length);
|
||||
scEl.textContent = sc;
|
||||
if (i >= items.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + sc + ' / ' + items.length;
|
||||
inp.disabled = true; btn.disabled = true;
|
||||
inp.style.opacity = .5; btn.style.opacity = .5;
|
||||
if (!bumped){ bumped = true; bumpProgress('p16', 25); addXp(15,'p16-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('p16');
|
||||
}
|
||||
|
||||
function buildP17(){
|
||||
const root = document.getElementById('p17-body');
|
||||
root.innerHTML = `
|
||||
<div class="card">
|
||||
<div class="card-header">
|
||||
<span class="card-icon theory">${ICONS.theory}</span>
|
||||
<span class="card-title">В разработке</span>
|
||||
<span class="card-num">§ 17</span>
|
||||
const box = document.getElementById('p17-body');
|
||||
let html = '';
|
||||
|
||||
html += makeCard('theory', 'Определение и формула $n$-го члена', '17.1', `
|
||||
<p><b>Геометрическая прогрессия</b> — числовая последовательность, в которой каждый следующий член равен предыдущему, умноженному на одно и то же число $q \\ne 0$ — <b>знаменатель прогрессии</b>.</p>
|
||||
<p>$$b_{n+1} = b_n \\cdot q,\\quad b_1 \\ne 0.$$</p>
|
||||
<p><b>Формула $n$-го члена:</b></p>
|
||||
<p>$$b_n = b_1 \\cdot q^{n - 1}.$$</p>
|
||||
<p><b>Пример.</b> $2, 6, 18, 54, \\ldots$ — геометрическая прогрессия с $b_1 = 2$, $q = 3$. Тогда $b_5 = 2 \\cdot 3^4 = 162$.</p>`);
|
||||
|
||||
html += makeCard('rule', 'Характеристическое свойство', '17.2', `
|
||||
<p>В геометрической прогрессии с положительными членами (или с одним знаком) <b>средний</b> член — это <b>среднее геометрическое</b> своих соседей:</p>
|
||||
<p>$$b_n^2 = b_{n-1} \\cdot b_{n+1}\\quad (n \\ge 2),$$</p>
|
||||
<p>то есть $|b_n| = \\sqrt{b_{n-1} \\cdot b_{n+1}}$.</p>
|
||||
<p><b>Пример.</b> Между $2$ и $8$ в геом. прогрессии стоит $\\sqrt{2 \\cdot 8} = \\sqrt{16} = 4$.</p>`);
|
||||
|
||||
html += makeCard('example', 'Применение формулы и поведение', '17.3', `
|
||||
<p><b>а)</b> $b_1 = 3$, $q = 2$: $b_5 = 3 \\cdot 2^4 = 3 \\cdot 16 = \\mathbf{48}.$</p>
|
||||
<p><b>б)</b> $b_1 = 64$, $q = \\dfrac{1}{2}$: $b_5 = 64 \\cdot \\left(\\dfrac{1}{2}\\right)^4 = 64 \\cdot \\dfrac{1}{16} = \\mathbf{4}.$ Прогрессия убывает по модулю.</p>
|
||||
<p><b>Поведение в зависимости от $q$:</b></p>
|
||||
<ul style="margin-left:18px">
|
||||
<li>$|q| > 1$ — модули членов <b>растут</b>;</li>
|
||||
<li>$|q| < 1$ — модули <b>убывают</b> к $0$;</li>
|
||||
<li>$|q| = 1$ — все члены равны по модулю;</li>
|
||||
<li>$q < 0$ — знаки членов <b>чередуются</b>.</li>
|
||||
</ul>`);
|
||||
|
||||
/* INTERACTIVE 1 — конструктор геометрической */
|
||||
html += `<div class="wg" id="p17-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Конструктор геом. прогрессии</div></div>
|
||||
<div class="wg-help">Двигай ползунки $b_1$ и $q$. Точки $(n; b_n)$ показывают, как ведёт себя прогрессия: рост / убывание / чередование знаков.</div>
|
||||
<div class="sliders">
|
||||
<label>$b_1$ =<b id="p17-iv1-bv">0</b><input type="range" id="p17-iv1-b1" min="-5" max="10" step="1" value="2"></label>
|
||||
<label>$q$ =<b id="p17-iv1-qv">0</b><input type="range" id="p17-iv1-q" min="-2" max="2" step="0.25" value="1.5"></label>
|
||||
</div>
|
||||
<div id="p17-iv1-formula" style="text-align:center;font-size:1.05rem;padding:10px;background:var(--card);border-radius:9px;margin-bottom:10px"></div>
|
||||
<div style="background:var(--card);border-radius:10px;padding:10px;overflow-x:auto">
|
||||
<svg id="p17-iv1-svg" viewBox="0 0 460 300" style="width:100%;max-width:560px;height:auto;display:block;margin:0 auto"></svg>
|
||||
</div>
|
||||
<div id="p17-iv1-out" style="margin-top:10px;padding:10px 14px;background:var(--sec-acc-soft);border-radius:9px;font-size:.92rem;text-align:center"></div>
|
||||
<div id="p17-iv1-desc" style="margin-top:8px;padding:8px 12px;background:var(--card);border-radius:8px;font-size:.9rem;text-align:center;color:var(--muted)"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — калькулятор b_n и q */
|
||||
html += `<div class="wg" id="p17-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор $b_n$ и $q$</div></div>
|
||||
<div class="wg-help">Две формы. <b>Слева</b> — найди $b_n$ по $b_1$, $q$, $n$. <b>Справа</b> — найди $q$ по $b_1$, $b_n$, $n$.</div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:14px;margin-bottom:8px">
|
||||
<div style="background:var(--card);border-radius:11px;padding:14px">
|
||||
<div style="font-weight:700;color:var(--sec-acc-d,var(--pri2));margin-bottom:10px">Найти $b_n$</div>
|
||||
<div style="display:grid;grid-template-columns:auto 1fr;gap:8px 10px;align-items:center;margin-bottom:10px">
|
||||
<span>$b_1$ =</span><input type="number" id="p17-iv2a-b1" class="tinp" value="2" step="1">
|
||||
<span>$q$ =</span><input type="number" id="p17-iv2a-q" class="tinp" value="3" step="0.5">
|
||||
<span>$n$ =</span><input type="number" id="p17-iv2a-n" class="tinp" value="5" step="1" min="1">
|
||||
</div>
|
||||
<button class="btn primary" id="p17-iv2a-go" style="width:100%">Найти $b_n$</button>
|
||||
<div id="p17-iv2a-out" style="margin-top:10px;padding:8px 12px;background:var(--sec-acc-soft);border-radius:8px;font-size:.92rem;min-height:36px"></div>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Содержание параграфа <b>«Геометрическая прогрессия»</b> будет добавлено в следующих обновлениях.</p>
|
||||
<p style="color:var(--muted);font-size:.9rem">Раздел Phase 1.</p>
|
||||
<div style="background:var(--card);border-radius:11px;padding:14px">
|
||||
<div style="font-weight:700;color:var(--sec-acc-d,var(--pri2));margin-bottom:10px">Найти $q$</div>
|
||||
<div style="display:grid;grid-template-columns:auto 1fr;gap:8px 10px;align-items:center;margin-bottom:10px">
|
||||
<span>$b_1$ =</span><input type="number" id="p17-iv2b-b1" class="tinp" value="2" step="1">
|
||||
<span>$b_n$ =</span><input type="number" id="p17-iv2b-bn" class="tinp" value="162" step="1">
|
||||
<span>$n$ =</span><input type="number" id="p17-iv2b-n" class="tinp" value="5" step="1" min="2">
|
||||
</div>
|
||||
<button class="btn primary" id="p17-iv2b-go" style="width:100%">Найти $q$</button>
|
||||
<div id="p17-iv2b-out" style="margin-top:10px;padding:8px 12px;background:var(--sec-acc-soft);border-radius:8px;font-size:.92rem;min-height:36px"></div>
|
||||
</div>
|
||||
</div>` + secNav('p16', 'p18') + readButton('p17');
|
||||
renderMath(root);
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — геометрическая или нет */
|
||||
html += `<div class="wg" id="p17-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Является ли геометрической?</div></div>
|
||||
<div class="wg-help">Даны первые члены последовательности. Если отношение $b_{n+1}/b_n$ постоянно — это геометрическая прогрессия.</div>
|
||||
<div class="score-display">Задача: <b id="p17-iv3-idx">1</b> / 6 · Очки: <b id="p17-iv3-sc">0</b></div>
|
||||
<div id="p17-iv3-q" style="text-align:center;font-size:1.05rem;padding:14px;background:var(--card);border-radius:9px;margin-bottom:12px;min-height:60px"></div>
|
||||
<div class="actions" style="justify-content:center">
|
||||
<button class="btn primary" id="p17-iv3-y">Да, геом.</button>
|
||||
<button class="btn" id="p17-iv3-n">Нет</button>
|
||||
</div>
|
||||
<div class="feedback" id="p17-iv3-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — тренажёр */
|
||||
html += `<div class="wg" id="p17-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр геом. прогрессии</div></div>
|
||||
<div class="wg-help">Применяй $b_n = b_1 \\cdot q^{n - 1}$ и характеристическое свойство $b_n^2 = b_{n-1} \\cdot b_{n+1}$. Ответ — целое число.</div>
|
||||
<div class="score-display">Задача: <b id="p17-iv4-idx">1</b> / 6 · Очки: <b id="p17-iv4-sc">0</b></div>
|
||||
<div id="p17-iv4-q" style="text-align:center;font-size:1.05rem;padding:14px;background:var(--card);border-radius:9px;margin-bottom:12px;min-height:60px"></div>
|
||||
<div class="actions" style="justify-content:center;align-items:center">
|
||||
<span style="font-family:'JetBrains Mono',monospace">Ответ:</span>
|
||||
<input type="number" id="p17-iv4-ans" class="tinp" style="width:120px;text-align:center" step="1">
|
||||
<button class="btn primary" id="p17-iv4-go">Проверить</button>
|
||||
</div>
|
||||
<div class="feedback" id="p17-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
box.innerHTML = html + secNav('p16', 'p18') + readButton('p17');
|
||||
renderMath(box);
|
||||
|
||||
/* ===== IV1 wiring ===== */
|
||||
(function(){
|
||||
const svg = document.getElementById('p17-iv1-svg');
|
||||
const b1Sl = document.getElementById('p17-iv1-b1');
|
||||
const qSl = document.getElementById('p17-iv1-q');
|
||||
const bv = document.getElementById('p17-iv1-bv');
|
||||
const qv = document.getElementById('p17-iv1-qv');
|
||||
const formula = document.getElementById('p17-iv1-formula');
|
||||
const out = document.getElementById('p17-iv1-out');
|
||||
const desc = document.getElementById('p17-iv1-desc');
|
||||
let bumped = false;
|
||||
|
||||
function fmtQ(q){
|
||||
// 1/2, 1/4 — для красоты
|
||||
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 - 0.25) < 1e-9) return '\\dfrac{1}{4}';
|
||||
if (Math.abs(q + 0.25) < 1e-9) return '-\\dfrac{1}{4}';
|
||||
if (Math.abs(q - 0.75) < 1e-9) return '\\dfrac{3}{4}';
|
||||
if (Math.abs(q + 0.75) < 1e-9) return '-\\dfrac{3}{4}';
|
||||
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;
|
||||
const q = +qSl.value;
|
||||
bv.textContent = b1; qv.textContent = q;
|
||||
|
||||
const N = 10;
|
||||
const pts = [];
|
||||
for (let n=1;n<=N;n++) pts.push([n, b1 * Math.pow(q, n-1)]);
|
||||
|
||||
// обрезаем чрезмерные значения для оси Y
|
||||
const ABS_LIMIT = 200;
|
||||
const ys = pts.map(p=>p[1]).filter(v=>Math.abs(v)<=ABS_LIMIT*5);
|
||||
let ymin = Math.min(...ys, 0), ymax = Math.max(...ys, 0);
|
||||
if (!isFinite(ymin) || !isFinite(ymax) || ymax === ymin){ ymin = -1; ymax = 1; }
|
||||
const pad = Math.max(2, (ymax - ymin) * 0.15);
|
||||
ymin = Math.floor(ymin - pad);
|
||||
ymax = Math.ceil(ymax + pad);
|
||||
|
||||
const ax = axes2D(460, 300, 34, 0, N+1, ymin, ymax);
|
||||
let g = ax.content;
|
||||
|
||||
// соединяющая ломаная (без хвостов вне зоны)
|
||||
let path = '';
|
||||
let prevIn = false;
|
||||
pts.forEach(p=>{
|
||||
const inZone = (p[1] >= ymin && p[1] <= ymax);
|
||||
if (inZone){
|
||||
path += (prevIn ? ' L' : ' M') + ax.toX(p[0]).toFixed(1) + ',' + ax.toY(p[1]).toFixed(1);
|
||||
}
|
||||
prevIn = inZone;
|
||||
});
|
||||
g += '<path d="'+path+'" stroke="#0891b2" stroke-width="1.5" fill="none" opacity=".55" stroke-dasharray="4 3"/>';
|
||||
|
||||
// точки
|
||||
pts.forEach(p=>{
|
||||
if (p[1] < ymin || p[1] > ymax) return;
|
||||
const x = ax.toX(p[0]); const y = ax.toY(p[1]);
|
||||
const color = (p[1] >= 0) ? '#0891b2' : '#ef4444';
|
||||
g += '<circle cx="'+x.toFixed(1)+'" cy="'+y.toFixed(1)+'" r="5" fill="'+color+'" stroke="#fff" stroke-width="2"/>';
|
||||
});
|
||||
svg.innerHTML = g;
|
||||
|
||||
// формула
|
||||
formula.innerHTML = '$b_n = ' + b1 + ' \\cdot (' + fmtQ(q) + ')^{n - 1}$';
|
||||
|
||||
// первые 6 членов
|
||||
const first6 = pts.slice(0,6).map(p=>fmt(+p[1].toFixed(4))).join(',\\ ');
|
||||
out.innerHTML = '<b>Первые 6 членов:</b> $' + first6 + ',\\ \\ldots$';
|
||||
|
||||
// описание поведения
|
||||
let txt = '';
|
||||
const aq = Math.abs(q);
|
||||
if (q === 0){ txt = 'При $q = 0$ прогрессия не определена (со 2-го члена все нули).'; }
|
||||
else if (aq > 1) txt = 'Модули растут (|q| > 1). ';
|
||||
else if (aq < 1) txt = 'Модули убывают к 0 (|q| < 1). ';
|
||||
else txt = 'Все члены по модулю равны $|b_1|$ (|q| = 1). ';
|
||||
if (q < 0) txt += 'Знаки чередуются (q < 0).';
|
||||
else if (q > 0) txt += 'Все члены одного знака (q > 0).';
|
||||
desc.textContent = txt;
|
||||
|
||||
renderMath(formula); renderMath(out);
|
||||
if (!bumped){ bumped = true; bumpProgress('p17', 15); addXp(10,'p17-iv1'); }
|
||||
}
|
||||
b1Sl.addEventListener('input', redraw);
|
||||
qSl.addEventListener('input', redraw);
|
||||
redraw();
|
||||
})();
|
||||
|
||||
/* ===== IV2 wiring ===== */
|
||||
(function(){
|
||||
// Найти b_n
|
||||
const outA = document.getElementById('p17-iv2a-out');
|
||||
let bumpedA = false;
|
||||
document.getElementById('p17-iv2a-go').addEventListener('click', ()=>{
|
||||
const b1 = +document.getElementById('p17-iv2a-b1').value;
|
||||
const q = +document.getElementById('p17-iv2a-q').value;
|
||||
const n = +document.getElementById('p17-iv2a-n').value;
|
||||
if (!Number.isInteger(n) || n < 1){ outA.innerHTML = 'Номер $n$ должен быть натуральным.'; renderMath(outA); return; }
|
||||
if (q === 0){ outA.innerHTML = 'Знаменатель $q$ должен быть $\\ne 0$.'; renderMath(outA); return; }
|
||||
const bn = b1 * Math.pow(q, n - 1);
|
||||
outA.innerHTML = '$b_{'+n+'} = '+b1+' \\cdot ('+fmt(q)+')^{'+n+' - 1} = '+b1+' \\cdot ('+fmt(q)+')^{'+(n-1)+'} = \\mathbf{'+fmt(+bn.toFixed(6))+'}$';
|
||||
renderMath(outA);
|
||||
if (!bumpedA){ bumpedA = true; bumpProgress('p17', 8); addXp(5,'p17-iv2a'); }
|
||||
});
|
||||
// Найти q
|
||||
const outB = document.getElementById('p17-iv2b-out');
|
||||
let bumpedB = false;
|
||||
document.getElementById('p17-iv2b-go').addEventListener('click', ()=>{
|
||||
const b1 = +document.getElementById('p17-iv2b-b1').value;
|
||||
const bn = +document.getElementById('p17-iv2b-bn').value;
|
||||
const n = +document.getElementById('p17-iv2b-n').value;
|
||||
if (!Number.isInteger(n) || n < 2){ outB.innerHTML = '$n$ должно быть целым и $\\ge 2$.'; renderMath(outB); return; }
|
||||
if (b1 === 0){ outB.innerHTML = 'Должно быть $b_1 \\ne 0$.'; renderMath(outB); return; }
|
||||
const ratio = bn / b1;
|
||||
const k = n - 1;
|
||||
// действительный корень (положительный)
|
||||
let qPos;
|
||||
if (ratio >= 0) qPos = Math.pow(ratio, 1/k);
|
||||
else if (k % 2 === 1) qPos = -Math.pow(-ratio, 1/k);
|
||||
else qPos = NaN;
|
||||
if (!isFinite(qPos) || isNaN(qPos)){
|
||||
outB.innerHTML = '$\\dfrac{b_n}{b_1} = '+fmt(ratio)+' < 0$, а степень $n - 1 = '+k+'$ чётная — действительного $q$ нет.';
|
||||
renderMath(outB); return;
|
||||
}
|
||||
outB.innerHTML = '$q^{'+k+'} = \\dfrac{b_n}{b_1} = \\dfrac{'+bn+'}{'+b1+'} = '+fmt(ratio)+'$ $\\Rightarrow$ $q = \\sqrt['+k+']{'+fmt(ratio)+'} = \\mathbf{'+fmt(+qPos.toFixed(6))+'}$';
|
||||
renderMath(outB);
|
||||
if (!bumpedB){ bumpedB = true; bumpProgress('p17', 7); addXp(5,'p17-iv2b'); }
|
||||
});
|
||||
})();
|
||||
|
||||
/* ===== IV3 wiring ===== */
|
||||
(function(){
|
||||
const items = [
|
||||
{ q:'$1,\\ 2,\\ 4,\\ 8,\\ \\ldots$', ans:true, hint:'Отношение $q = 2$ постоянно.' },
|
||||
{ q:'$3,\\ 6,\\ 9,\\ 12,\\ \\ldots$', ans:false, hint:'Отношения $2, 1.5, \\tfrac{4}{3}$ — разные. Это арифметическая ($d = 3$).' },
|
||||
{ q:'$5,\\ 5,\\ 5,\\ 5,\\ \\ldots$', ans:true, hint:'Это геом. прогрессия с $q = 1$ (и одновременно арифм. с $d = 0$).' },
|
||||
{ q:'$81,\\ -27,\\ 9,\\ -3,\\ \\ldots$', ans:true, hint:'$q = -\\dfrac{1}{3}$ постоянна — знаки чередуются.' },
|
||||
{ q:'$2,\\ 4,\\ 6,\\ 8,\\ \\ldots$', ans:false, hint:'Отношения $2, 1.5, \\tfrac{4}{3}$ — не равны. Это арифм. с $d = 2$.' },
|
||||
{ q:'$1,\\ \\dfrac{1}{2},\\ \\dfrac{1}{4},\\ \\dfrac{1}{8},\\ \\ldots$', ans:true, hint:'$q = \\dfrac{1}{2}$ постоянна.' }
|
||||
];
|
||||
let i = 0, sc = 0;
|
||||
const idxEl = document.getElementById('p17-iv3-idx');
|
||||
const scEl = document.getElementById('p17-iv3-sc');
|
||||
const qEl = document.getElementById('p17-iv3-q');
|
||||
const fb = document.getElementById('p17-iv3-fb');
|
||||
const yBtn = document.getElementById('p17-iv3-y');
|
||||
const nBtn = document.getElementById('p17-iv3-n');
|
||||
let bumped = false;
|
||||
function render(){
|
||||
idxEl.textContent = Math.min(i+1, items.length);
|
||||
scEl.textContent = sc;
|
||||
if (i >= items.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + sc + ' / ' + items.length;
|
||||
yBtn.disabled = true; nBtn.disabled = true;
|
||||
yBtn.style.opacity = .5; nBtn.style.opacity = .5;
|
||||
if (!bumped){ bumped = true; bumpProgress('p17', 25); addXp(15,'p17-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, 1100);
|
||||
}
|
||||
yBtn.addEventListener('click', ()=>answer(true));
|
||||
nBtn.addEventListener('click', ()=>answer(false));
|
||||
render();
|
||||
})();
|
||||
|
||||
/* ===== IV4 wiring — тренажёр ===== */
|
||||
(function(){
|
||||
const items = [
|
||||
{ q:'$b_1 = 2,\\ q = 3$. Найти $b_4$.', ans: 54 },
|
||||
{ q:'$b_1 = 64,\\ q = \\dfrac{1}{2}$. Найти $b_5$.', ans: 4 },
|
||||
{ q:'$b_1 = 5,\\ b_3 = 45$. Найти $q$ (положительный).', ans: 3 },
|
||||
{ q:'$b_2 = 6,\\ b_4 = 24$. Найти $q$ (положительный).', ans: 2 },
|
||||
{ q:'Найти среднее геометрическое чисел $2$ и $8$ (положительное).', ans: 4 },
|
||||
{ q:'$b_1 = 3,\\ q = -2$. Найти $b_4$.', ans: -24 }
|
||||
];
|
||||
let i = 0, sc = 0;
|
||||
const idxEl = document.getElementById('p17-iv4-idx');
|
||||
const scEl = document.getElementById('p17-iv4-sc');
|
||||
const qEl = document.getElementById('p17-iv4-q');
|
||||
const inp = document.getElementById('p17-iv4-ans');
|
||||
const btn = document.getElementById('p17-iv4-go');
|
||||
const fb = document.getElementById('p17-iv4-fb');
|
||||
let bumped = false;
|
||||
function render(){
|
||||
idxEl.textContent = Math.min(i+1, items.length);
|
||||
scEl.textContent = sc;
|
||||
if (i >= items.length){
|
||||
qEl.innerHTML = '<b>Готово!</b> Результат: ' + sc + ' / ' + items.length;
|
||||
inp.disabled = true; btn.disabled = true;
|
||||
inp.style.opacity = .5; btn.style.opacity = .5;
|
||||
if (!bumped){ bumped = true; bumpProgress('p17', 25); addXp(15,'p17-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('p17');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user