feat(alg9 ch1 wave2): §3 «Сложение и вычитание» + §4 «Умножение и деление»
This commit is contained in:
@@ -993,38 +993,512 @@ function buildP2(){
|
||||
}
|
||||
|
||||
function buildP3(){
|
||||
const root = document.getElementById('p3-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">§ 3</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Содержание параграфа <b>«Сложение и вычитание»</b> будет добавлено в следующих обновлениях.</p>
|
||||
<p style="color:var(--muted);font-size:.9rem">Раздел Phase 1.</p>
|
||||
</div>
|
||||
</div>` + secNav('p2', 'p4') + readButton('p3');
|
||||
renderMath(root);
|
||||
const box = document.getElementById('p3-body');
|
||||
let html = '';
|
||||
|
||||
html += makeCard('theory', 'С одинаковыми знаменателями', '3.1', `
|
||||
<p>Чтобы сложить (или вычесть) рациональные дроби с <b>одинаковыми знаменателями</b>, надо сложить (вычесть) их числители, а знаменатель оставить прежним:</p>
|
||||
\\[\\dfrac{A}{C} + \\dfrac{B}{C} = \\dfrac{A+B}{C}, \\qquad \\dfrac{A}{C} - \\dfrac{B}{C} = \\dfrac{A-B}{C}, \\quad C \\ne 0.\\]
|
||||
<p>Примеры:</p>
|
||||
<ul style="padding-left:22px;line-height:1.9">
|
||||
<li>$\\dfrac{x}{5} + \\dfrac{3}{5} = \\dfrac{x+3}{5}$</li>
|
||||
<li>$\\dfrac{2a}{a-1} - \\dfrac{a+5}{a-1} = \\dfrac{2a - (a+5)}{a-1} = \\dfrac{a-5}{a-1}$ — не забывай менять знаки при вычитании!</li>
|
||||
</ul>
|
||||
<details class="spoiler"><summary>Часто допускаемая ошибка</summary><div class="spoiler-body">
|
||||
При вычитании всегда заключай числитель вычитаемой дроби в <b>скобки</b>: $\\dfrac{A}{C} - \\dfrac{B}{C} = \\dfrac{A - (B)}{C}$, иначе можно «потерять» минус и получить $A - B$ вместо $A - B_1 + B_2$.
|
||||
</div></details>`);
|
||||
|
||||
html += makeCard('rule', 'С разными знаменателями · Алгоритм', '3.2', `
|
||||
<p>Если знаменатели <b>разные</b> — приводим дроби к общему знаменателю.</p>
|
||||
<ol style="padding-left:22px;line-height:2">
|
||||
<li><b>Разложить</b> каждый знаменатель на множители.</li>
|
||||
<li><b>Найти НОЗ</b> — наименьший общий знаменатель: произведение всех различных множителей, взятых в <b>наивысших</b> степенях.</li>
|
||||
<li><b>Привести</b> каждую дробь к НОЗ: умножить числитель и знаменатель на нужный <b>дополнительный множитель</b>.</li>
|
||||
<li><b>Сложить/вычесть</b> числители (знаменатель — НОЗ).</li>
|
||||
<li><b>Сократить</b> результат, если возможно.</li>
|
||||
</ol>
|
||||
<p>Пример НОЗ:</p>
|
||||
<ul style="padding-left:22px;line-height:1.8">
|
||||
<li>$\\dfrac{1}{2x}$ и $\\dfrac{1}{3x}$ → НОЗ $= 6x$ (НОК(2,3) $= 6$, $x$ один раз).</li>
|
||||
<li>$\\dfrac{1}{x-2}$ и $\\dfrac{1}{x^2-4}$ → $x^2-4 = (x-2)(x+2)$, НОЗ $= (x-2)(x+2)$.</li>
|
||||
</ul>`);
|
||||
|
||||
html += makeCard('example', 'Примеры пошагово', '3.3', `
|
||||
<p><b>Пример 1.</b> $\\dfrac{1}{x-2} + \\dfrac{1}{x+2}$. НОЗ $= (x-2)(x+2) = x^2 - 4$.</p>
|
||||
\\[\\dfrac{1}{x-2} + \\dfrac{1}{x+2} = \\dfrac{(x+2) + (x-2)}{(x-2)(x+2)} = \\dfrac{2x}{x^2-4}.\\]
|
||||
<p><b>Пример 2.</b> $\\dfrac{2}{a} - \\dfrac{3}{a^2}$. НОЗ $= a^2$. Дополнительный множитель для $\\dfrac{2}{a}$ равен $a$:</p>
|
||||
\\[\\dfrac{2}{a} - \\dfrac{3}{a^2} = \\dfrac{2a}{a^2} - \\dfrac{3}{a^2} = \\dfrac{2a - 3}{a^2}.\\]
|
||||
<p><b>Пример 3 (с сокращением).</b> $\\dfrac{1}{x-1} - \\dfrac{1}{x+1} = \\dfrac{(x+1) - (x-1)}{(x-1)(x+1)} = \\dfrac{2}{x^2-1}.$</p>`);
|
||||
|
||||
/* INTERACTIVE 1 — Конструктор НОЗ */
|
||||
html += `<div class="wg" id="p3-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Конструктор НОЗ</div></div>
|
||||
<div class="wg-help">Выбери пару знаменателей — увидишь разложение каждого, НОЗ и дополнительные множители.</div>
|
||||
<div class="sliders">
|
||||
<label>Пара №<b id="p3-iv1-idx">1</b> / 5<input type="range" id="p3-iv1-sl" min="1" max="5" step="1" value="1"></label>
|
||||
</div>
|
||||
<div id="p3-iv1-pair" style="text-align:center;font-size:1.1rem;padding:12px;background:var(--card);border-radius:9px;margin-bottom:10px"></div>
|
||||
<div style="display:flex;gap:10px;justify-content:center;margin-bottom:10px">
|
||||
<button class="btn primary" id="p3-iv1-go">Найти НОЗ</button>
|
||||
<button class="btn" id="p3-iv1-hide">Скрыть</button>
|
||||
</div>
|
||||
<div id="p3-iv1-out" style="padding:12px;background:var(--sec-acc-soft);border-radius:9px;font-size:1rem;min-height:50px;display:none"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Калькулятор сложения */
|
||||
html += `<div class="wg" id="p3-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор $\\dfrac{A}{C} \\pm \\dfrac{B}{C}$</div></div>
|
||||
<div class="wg-help">Введи целые числители $A$ и $B$, выбери знак и знаменатель $C$ — получишь результат.</div>
|
||||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:center;margin-bottom:10px">
|
||||
<span>$A =$</span>
|
||||
<input type="number" id="p3-iv2-a" class="tinp" style="width:80px;text-align:center" value="3">
|
||||
<select id="p3-iv2-op" class="tinp" style="width:60px;text-align:center;font-size:1.1rem">
|
||||
<option value="+">+</option>
|
||||
<option value="-">−</option>
|
||||
</select>
|
||||
<span>$B =$</span>
|
||||
<input type="number" id="p3-iv2-b" class="tinp" style="width:80px;text-align:center" value="5">
|
||||
<span>над $C =$</span>
|
||||
<select id="p3-iv2-c" class="tinp" style="width:90px;text-align:center">
|
||||
<option value="x">x</option>
|
||||
<option value="x+1">x+1</option>
|
||||
<option value="x-2">x-2</option>
|
||||
<option value="2">2</option>
|
||||
<option value="5">5</option>
|
||||
</select>
|
||||
<button class="btn primary" id="p3-iv2-go">Вычислить</button>
|
||||
</div>
|
||||
<div id="p3-iv2-out" style="padding:12px;background:var(--card);border-radius:9px;text-align:center;font-size:1.05rem;min-height:50px"></div>
|
||||
<div class="feedback" id="p3-iv2-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — DnD-сортер: какой НОЗ? */
|
||||
html += `<div class="wg" id="p3-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Какой НОЗ?</div></div>
|
||||
<div class="wg-help">Перетащи каждую пару знаменателей в нужный ящик: тип НОЗ.</div>
|
||||
<div class="dnd-hint"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M9 11V6a3 3 0 0 1 6 0v5"/><path d="M9 11h6v8a4 4 0 0 1-8 0z"/></svg> 6 пар — 3 типа НОЗ</div>
|
||||
<div id="p3-iv3-pool"></div>
|
||||
<div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px;margin-top:8px">
|
||||
<div class="drop-box"><h5 data-cat="prod">Произведение знаменателей</h5><div class="drop-items" data-cat="prod"></div></div>
|
||||
<div class="drop-box"><h5 data-cat="one">Один из знаменателей</h5><div class="drop-items" data-cat="one"></div></div>
|
||||
<div class="drop-box"><h5 data-cat="num">Просто число</h5><div class="drop-items" data-cat="num"></div></div>
|
||||
</div>
|
||||
<div class="actions"><button class="btn primary" id="p3-iv3-check">Проверить</button><button class="btn" id="p3-iv3-reset">Сначала</button></div>
|
||||
<div class="feedback" id="p3-iv3-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр сложения/вычитания */
|
||||
html += `<div class="wg" id="p3-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр сложения и вычитания</div></div>
|
||||
<div class="wg-help">Реши пример и введи число, которое спрашивают в подсказке.</div>
|
||||
<div class="score-display"><span>Задача <b id="p3-iv4-i">1</b> / 6</span><span>Очки: <b id="p3-iv4-s">0</b> / 6</span></div>
|
||||
<div id="p3-iv4-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center"></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span id="p3-iv4-prompt" style="font-family:'JetBrains Mono',monospace;font-size:.95rem">ответ =</span>
|
||||
<input type="number" id="p3-iv4-ans" class="tinp" style="width:100px;text-align:center">
|
||||
<button class="btn primary" id="p3-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p3-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p3-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p2', 'p4');
|
||||
html += readButton('p3');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Конструктор НОЗ */
|
||||
(function(){
|
||||
const PAIRS = [
|
||||
{ d1:'x', d2:'3x', fact1:'x', fact2:'3 \\cdot x', lcm:'3x', add1:'3', add2:'1' },
|
||||
{ d1:'x-1', d2:'x+1', fact1:'(x-1)', fact2:'(x+1)', lcm:'(x-1)(x+1) = x^2 - 1', add1:'(x+1)', add2:'(x-1)' },
|
||||
{ d1:'x-2', d2:'x^2-4', fact1:'(x-2)', fact2:'(x-2)(x+2)', lcm:'(x-2)(x+2)', add1:'(x+2)', add2:'1' },
|
||||
{ d1:'2x', d2:'3x', fact1:'2 \\cdot x', fact2:'3 \\cdot x', lcm:'6x', add1:'3', add2:'2' },
|
||||
{ d1:'x', d2:'x^2', fact1:'x', fact2:'x \\cdot x', lcm:'x^2', add1:'x', add2:'1' },
|
||||
];
|
||||
const sl = document.getElementById('p3-iv1-sl');
|
||||
const idx = document.getElementById('p3-iv1-idx');
|
||||
const pEl = document.getElementById('p3-iv1-pair');
|
||||
const out = document.getElementById('p3-iv1-out');
|
||||
const go = document.getElementById('p3-iv1-go');
|
||||
const hide= document.getElementById('p3-iv1-hide');
|
||||
const seen = new Set();
|
||||
function show(){
|
||||
const k = +sl.value; idx.textContent = k;
|
||||
const p = PAIRS[k-1];
|
||||
pEl.innerHTML = 'Знаменатели: $'+p.d1+'$ и $'+p.d2+'$';
|
||||
out.innerHTML = '<div>Разложение: $'+p.d1+' = '+p.fact1+'$, $'+p.d2+' = '+p.fact2+'$</div>'
|
||||
+ '<div style="margin-top:6px"><b>НОЗ $= '+p.lcm+'$</b></div>'
|
||||
+ '<div style="margin-top:6px;font-size:.92rem;color:var(--muted)">Доп. множители: к $\\dfrac{?}{'+p.d1+'}$ → $'+p.add1+'$; к $\\dfrac{?}{'+p.d2+'}$ → $'+p.add2+'$</div>';
|
||||
out.style.display = 'none';
|
||||
renderMath(pEl);
|
||||
seen.add(k);
|
||||
if(seen.size === PAIRS.length && !seen.has('done')){ addXp(10,'p3-iv1'); bumpProgress('p3', 15); seen.add('done'); }
|
||||
}
|
||||
sl.addEventListener('input', show);
|
||||
go.addEventListener('click', ()=>{ out.style.display = 'block'; renderMath(out); });
|
||||
hide.addEventListener('click', ()=>{ out.style.display = 'none'; });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV2 — Калькулятор A/C ± B/C */
|
||||
(function(){
|
||||
const aI = document.getElementById('p3-iv2-a');
|
||||
const bI = document.getElementById('p3-iv2-b');
|
||||
const opI= document.getElementById('p3-iv2-op');
|
||||
const cI = document.getElementById('p3-iv2-c');
|
||||
const out= document.getElementById('p3-iv2-out');
|
||||
const fb = document.getElementById('p3-iv2-fb');
|
||||
const go = document.getElementById('p3-iv2-go');
|
||||
let solved = 0;
|
||||
function calc(){
|
||||
const a = parseInt(aI.value, 10), b = parseInt(bI.value, 10);
|
||||
const op= opI.value;
|
||||
const c = cI.value;
|
||||
if(isNaN(a) || isNaN(b)){ feedback(fb, false, '✗ Введи целые числа $A$ и $B$.'); return; }
|
||||
const sum = (op === '+') ? a + b : a - b;
|
||||
const numericC = /^\d+$/.test(c);
|
||||
let resHtml;
|
||||
if(sum === 0){
|
||||
resHtml = '$\\dfrac{'+a+'}{'+c+'} '+op+' \\dfrac{'+b+'}{'+c+'} = \\dfrac{0}{'+c+'} = 0$';
|
||||
} else if(numericC){
|
||||
const C = parseInt(c, 10);
|
||||
const g = gcd(Math.abs(sum), C);
|
||||
const n2 = sum/g, d2 = C/g;
|
||||
if(d2 === 1) resHtml = '$\\dfrac{'+a+'}{'+c+'} '+op+' \\dfrac{'+b+'}{'+c+'} = \\dfrac{'+sum+'}{'+c+'} = '+n2+'$';
|
||||
else if(g === 1) resHtml = '$\\dfrac{'+a+'}{'+c+'} '+op+' \\dfrac{'+b+'}{'+c+'} = \\dfrac{'+sum+'}{'+c+'}$';
|
||||
else resHtml = '$\\dfrac{'+a+'}{'+c+'} '+op+' \\dfrac{'+b+'}{'+c+'} = \\dfrac{'+sum+'}{'+c+'} = \\dfrac{'+n2+'}{'+d2+'}$';
|
||||
} else {
|
||||
resHtml = '$\\dfrac{'+a+'}{'+c+'} '+op+' \\dfrac{'+b+'}{'+c+'} = \\dfrac{'+sum+'}{'+c+'}$';
|
||||
}
|
||||
out.innerHTML = resHtml;
|
||||
renderMath(out);
|
||||
feedback(fb, true, '✓ Готово! +10 XP');
|
||||
solved++;
|
||||
if(solved === 1){ addXp(10,'p3-iv2'); bumpProgress('p3', 15); }
|
||||
}
|
||||
go.addEventListener('click', calc);
|
||||
calc();
|
||||
})();
|
||||
|
||||
/* IV3 — DnD сортер НОЗ */
|
||||
(function(){
|
||||
const items = [
|
||||
{ id:'s1', cat:'prod', html:'$x$ и $x+1$' },
|
||||
{ id:'s2', cat:'one', html:'$x-3$ и $2(x-3)$' },
|
||||
{ id:'s3', cat:'prod', html:'$x-1$ и $x+1$' },
|
||||
{ id:'s4', cat:'num', html:'$4$ и $6$' },
|
||||
{ id:'s5', cat:'one', html:'$x^2$ и $x^3$' },
|
||||
{ id:'s6', cat:'one', html:'$x$ и $x^2-x$' },
|
||||
];
|
||||
const sorter = setupSorter({
|
||||
poolId:'p3-iv3-pool',
|
||||
scopeSelector:'#p3-iv3',
|
||||
items: items,
|
||||
cats:['prod','one','num'],
|
||||
columnLayout:true,
|
||||
});
|
||||
document.getElementById('p3-iv3-check').addEventListener('click', ()=>{
|
||||
const fb = document.getElementById('p3-iv3-fb');
|
||||
const placedCount = items.filter(it => sorter.placed[it.id]).length;
|
||||
const correct = items.filter(it => sorter.placed[it.id] === it.cat).length;
|
||||
if(placedCount < items.length){ feedback(fb, false, '✗ Размести все 6 пар.'); return; }
|
||||
if(correct === items.length){ feedback(fb, true, '✓ Все 6 на месте! +15 XP'); addXp(15,'p3-iv3'); bumpProgress('p3', 25); }
|
||||
else feedback(fb, false, '✗ Правильно ' + correct + ' из 6. Попробуй ещё.');
|
||||
});
|
||||
document.getElementById('p3-iv3-reset').addEventListener('click', ()=>{ sorter.reset(); document.getElementById('p3-iv3-fb').style.display = 'none'; });
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'$\\dfrac{3}{x} + \\dfrac{5}{x}$', ans:8, prompt:'числитель =', hint:'сложили $3 + 5 = 8$, знаменатель тот же', res:'\\dfrac{8}{x}' },
|
||||
{ q:'$\\dfrac{7}{a} - \\dfrac{4}{a}$', ans:3, prompt:'числитель =', hint:'$7 - 4 = 3$', res:'\\dfrac{3}{a}' },
|
||||
{ q:'$\\dfrac{1}{x-1} + \\dfrac{1}{x-1}$', ans:2, prompt:'числитель =', hint:'$1 + 1 = 2$', res:'\\dfrac{2}{x-1}' },
|
||||
{ q:'$\\dfrac{x}{2} + \\dfrac{x}{3}$', ans:5, prompt:'коэф. при x =', hint:'НОЗ $= 6$: $\\dfrac{3x + 2x}{6} = \\dfrac{5x}{6}$', res:'\\dfrac{5x}{6}' },
|
||||
{ q:'$\\dfrac{1}{x} - \\dfrac{1}{x^2}$', ans:2, prompt:'показатель x в знаменателе =', hint:'НОЗ $= x^2$, числитель $= x - 1$', res:'\\dfrac{x-1}{x^2}' },
|
||||
{ q:'$\\dfrac{2}{x+1} + \\dfrac{3}{x+1}$', ans:5, prompt:'числитель =', hint:'$2 + 3 = 5$', res:'\\dfrac{5}{x+1}' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p3-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
document.getElementById('p3-iv4-prompt').textContent = 'ответ =';
|
||||
if(score === Q.length){ addXp(15,'p3-iv4'); bumpProgress('p3', 25); }
|
||||
else if(score >= 4){ addXp(8,'p3-iv4'); bumpProgress('p3', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p3-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p3-iv4-s').textContent = score;
|
||||
document.getElementById('p3-iv4-q').innerHTML = 'Найди: ' + Q[i].q;
|
||||
document.getElementById('p3-iv4-prompt').textContent = Q[i].prompt;
|
||||
document.getElementById('p3-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p3-iv4-q'));
|
||||
document.getElementById('p3-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p3-iv4-fb');
|
||||
const ans = parseInt(document.getElementById('p3-iv4-ans').value, 10);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи целое число.'); return; }
|
||||
if(ans === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! Ответ: $' + Q[i].res + '$ ('+Q[i].hint+'). Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Должно быть $' + Q[i].ans + '$. Ответ: $' + Q[i].res + '$ ('+Q[i].hint+'). Дальше ▶');
|
||||
document.getElementById('p3-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1400);
|
||||
}
|
||||
document.getElementById('p3-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p3-iv4-ans').addEventListener('keydown', e=>{ if(e.key === 'Enter') go(); });
|
||||
document.getElementById('p3-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p3');
|
||||
}
|
||||
|
||||
function buildP4(){
|
||||
const root = document.getElementById('p4-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">§ 4</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p>Содержание параграфа <b>«Умножение и деление»</b> будет добавлено в следующих обновлениях.</p>
|
||||
<p style="color:var(--muted);font-size:.9rem">Раздел Phase 1.</p>
|
||||
</div>
|
||||
</div>` + secNav('p3', 'p5') + readButton('p4');
|
||||
renderMath(root);
|
||||
const box = document.getElementById('p4-body');
|
||||
let html = '';
|
||||
|
||||
html += makeCard('theory', 'Умножение дробей', '4.1', `
|
||||
<p>Чтобы <b>умножить</b> две рациональные дроби, надо перемножить их числители и перемножить знаменатели:</p>
|
||||
\\[\\dfrac{A}{B} \\cdot \\dfrac{C}{D} = \\dfrac{A \\cdot C}{B \\cdot D}, \\quad B \\ne 0,\\ D \\ne 0.\\]
|
||||
<p>Чаще удобно <b>сократить</b> общие множители <i>до</i> умножения — это упрощает вычисления.</p>
|
||||
<p>Пример: $\\dfrac{2x}{3} \\cdot \\dfrac{5}{x^2} = \\dfrac{2x \\cdot 5}{3 \\cdot x^2} = \\dfrac{10x}{3x^2} = \\dfrac{10}{3x}$ — сократили $x$.</p>
|
||||
<details class="spoiler"><summary>Можно ли «крест-накрест»?</summary><div class="spoiler-body">
|
||||
При умножении сокращать можно <b>любой</b> множитель числителя с <b>любым</b> множителем знаменателя (даже «крест-накрест»): $\\dfrac{a}{b} \\cdot \\dfrac{b}{c} = \\dfrac{a}{c}$, $b$ ушло.
|
||||
</div></details>`);
|
||||
|
||||
html += makeCard('rule', 'Деление дробей · Правило', '4.2', `
|
||||
<p>Чтобы <b>разделить</b> одну рациональную дробь на другую, надо первую дробь умножить на <b>обратную</b> ко второй:</p>
|
||||
\\[\\dfrac{A}{B} : \\dfrac{C}{D} = \\dfrac{A}{B} \\cdot \\dfrac{D}{C} = \\dfrac{A \\cdot D}{B \\cdot C}, \\quad B \\ne 0,\\ C \\ne 0,\\ D \\ne 0.\\]
|
||||
<p><b>Обратная дробь</b> к $\\dfrac{C}{D}$ — это $\\dfrac{D}{C}$ (числитель и знаменатель меняются местами).</p>
|
||||
<p>Условие $C \\ne 0$ возникает потому, что мы делим на дробь $\\dfrac{C}{D}$, а на ноль делить нельзя.</p>
|
||||
<p style="background:var(--warn-bg);padding:8px 12px;border-radius:8px;border-left:3px solid var(--warn)"><b>Запомни:</b> деление = умножение на <i>перевёрнутую</i> дробь. После этого работаем как с обычным умножением.</p>`);
|
||||
|
||||
html += makeCard('example', 'Возведение дроби в степень', '4.3', `
|
||||
<p>Чтобы возвести дробь в натуральную степень $n$, надо возвести в эту степень и числитель, и знаменатель:</p>
|
||||
\\[\\left(\\dfrac{A}{B}\\right)^n = \\dfrac{A^n}{B^n}, \\quad B \\ne 0.\\]
|
||||
<p>Примеры:</p>
|
||||
<ul style="padding-left:22px;line-height:1.9">
|
||||
<li>$\\left(\\dfrac{2}{x}\\right)^3 = \\dfrac{2^3}{x^3} = \\dfrac{8}{x^3}$</li>
|
||||
<li>$\\left(\\dfrac{x-1}{x+1}\\right)^2 = \\dfrac{(x-1)^2}{(x+1)^2}$ — скобки обязательны!</li>
|
||||
<li>$\\left(\\dfrac{3a}{b^2}\\right)^2 = \\dfrac{9a^2}{b^4}$</li>
|
||||
</ul>`);
|
||||
|
||||
/* INTERACTIVE 1 — Умножение с подсветкой */
|
||||
html += `<div class="wg" id="p4-iv1">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 1</span><div class="wg-title">Умножение с подсветкой</div></div>
|
||||
<div class="wg-help">Выбери задачу — увидишь произведение дробей. Нажми «Показать шаги», чтобы увидеть сокращение.</div>
|
||||
<div class="sliders">
|
||||
<label>Задача №<b id="p4-iv1-idx">1</b> / 5<input type="range" id="p4-iv1-sl" min="1" max="5" step="1" value="1"></label>
|
||||
</div>
|
||||
<div id="p4-iv1-before" style="text-align:center;font-size:1.2rem;padding:14px;background:var(--card);border-radius:9px;margin-bottom:10px;min-height:60px"></div>
|
||||
<div style="display:flex;gap:10px;justify-content:center;margin-bottom:10px">
|
||||
<button class="btn primary" id="p4-iv1-go">Показать шаги</button>
|
||||
<button class="btn" id="p4-iv1-hide">Скрыть</button>
|
||||
</div>
|
||||
<div id="p4-iv1-after" style="text-align:center;font-size:1.1rem;padding:14px;background:var(--sec-acc-soft);border-radius:9px;min-height:50px;display:none"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 2 — Калькулятор деления a/b : c/d */
|
||||
html += `<div class="wg" id="p4-iv2">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 2</span><div class="wg-title">Калькулятор деления $\\dfrac{a}{b} : \\dfrac{c}{d}$</div></div>
|
||||
<div class="wg-help">Введи целые $a, b, c, d$ — увидишь преобразование к умножению и упрощённый результат.</div>
|
||||
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap;justify-content:center;margin-bottom:10px">
|
||||
<span>$a =$</span><input type="number" id="p4-iv2-a" class="tinp" style="width:70px;text-align:center" value="3">
|
||||
<span>$b =$</span><input type="number" id="p4-iv2-b" class="tinp" style="width:70px;text-align:center" value="4">
|
||||
<span>$c =$</span><input type="number" id="p4-iv2-c" class="tinp" style="width:70px;text-align:center" value="9">
|
||||
<span>$d =$</span><input type="number" id="p4-iv2-d" class="tinp" style="width:70px;text-align:center" value="8">
|
||||
<button class="btn primary" id="p4-iv2-go">Вычислить</button>
|
||||
</div>
|
||||
<div id="p4-iv2-out" style="padding:12px;background:var(--card);border-radius:9px;text-align:center;font-size:1rem;min-height:50px"></div>
|
||||
<div class="feedback" id="p4-iv2-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 3 — Найди ошибку */
|
||||
html += `<div class="wg" id="p4-iv3">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 3</span><div class="wg-title">Верно или ошибка?</div></div>
|
||||
<div class="wg-help">Реши каждое преобразование: верно оно или нет. 6 заданий.</div>
|
||||
<div class="score-display"><span>Задача <b id="p4-iv3-i">1</b> / 6</span><span>Очки: <b id="p4-iv3-s">0</b> / 6</span></div>
|
||||
<div id="p4-iv3-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.1rem;text-align:center;margin-bottom:10px"></div>
|
||||
<div style="display:flex;gap:10px;justify-content:center;flex-wrap:wrap">
|
||||
<button class="btn primary" id="p4-iv3-ok" style="background:#10b981;border-color:#10b981">Верно</button>
|
||||
<button class="btn primary" id="p4-iv3-err" style="background:#dc2626;border-color:#dc2626">Ошибка</button>
|
||||
</div>
|
||||
<div class="feedback" id="p4-iv3-fb"></div>
|
||||
</div>`;
|
||||
|
||||
/* INTERACTIVE 4 — Тренажёр умножения и деления */
|
||||
html += `<div class="wg" id="p4-iv4">
|
||||
<div class="wg-header"><span class="wg-badge">ИНТЕРАКТИВ 4</span><div class="wg-title">Тренажёр умножения и деления</div></div>
|
||||
<div class="wg-help">Вычисли и введи число, которое спрашивают в подсказке.</div>
|
||||
<div class="score-display"><span>Задача <b id="p4-iv4-i">1</b> / 6</span><span>Очки: <b id="p4-iv4-s">0</b> / 6</span></div>
|
||||
<div id="p4-iv4-q" style="padding:14px;background:var(--sec-acc-soft);border-radius:10px;font-size:1.05rem;margin-bottom:10px;text-align:center"></div>
|
||||
<div style="display:flex;gap:10px;align-items:center;flex-wrap:wrap;justify-content:center">
|
||||
<span id="p4-iv4-prompt" style="font-family:'JetBrains Mono',monospace;font-size:.95rem">ответ =</span>
|
||||
<input type="number" id="p4-iv4-ans" class="tinp" style="width:100px;text-align:center">
|
||||
<button class="btn primary" id="p4-iv4-go">Проверить</button>
|
||||
<button class="btn" id="p4-iv4-start">Заново</button>
|
||||
</div>
|
||||
<div class="feedback" id="p4-iv4-fb"></div>
|
||||
</div>`;
|
||||
|
||||
html += secNav('p3', 'p5');
|
||||
html += readButton('p4');
|
||||
|
||||
box.innerHTML = html;
|
||||
renderMath(box);
|
||||
|
||||
/* IV1 — Умножение со скрытием шагов */
|
||||
(function(){
|
||||
const T = [
|
||||
{ before:'\\dfrac{3}{x} \\cdot \\dfrac{x}{5}', steps:'\\dfrac{3 \\cdot x}{x \\cdot 5} = \\dfrac{3x}{5x}', after:'\\dfrac{3}{5}', note:'сократили $x$' },
|
||||
{ before:'\\dfrac{2a}{b^2} \\cdot \\dfrac{b}{4}', steps:'\\dfrac{2a \\cdot b}{b^2 \\cdot 4} = \\dfrac{2ab}{4b^2}', after:'\\dfrac{a}{2b}', note:'сократили $2b$' },
|
||||
{ before:'\\dfrac{x+1}{x-1} \\cdot \\dfrac{x-1}{x+2}', steps:'\\dfrac{(x+1)(x-1)}{(x-1)(x+2)}', after:'\\dfrac{x+1}{x+2}', note:'сократили $(x-1)$' },
|
||||
{ before:'\\dfrac{6}{x^2} \\cdot \\dfrac{x}{2}', steps:'\\dfrac{6 \\cdot x}{x^2 \\cdot 2} = \\dfrac{6x}{2x^2}', after:'\\dfrac{3}{x}', note:'сократили $2x$' },
|
||||
{ before:'\\dfrac{x-3}{4} \\cdot \\dfrac{8}{(x-3)^2}', steps:'\\dfrac{(x-3) \\cdot 8}{4 \\cdot (x-3)^2} = \\dfrac{8(x-3)}{4(x-3)^2}', after:'\\dfrac{2}{x-3}', note:'сократили $4(x-3)$' },
|
||||
];
|
||||
const sl = document.getElementById('p4-iv1-sl');
|
||||
const idx = document.getElementById('p4-iv1-idx');
|
||||
const bEl = document.getElementById('p4-iv1-before');
|
||||
const aEl = document.getElementById('p4-iv1-after');
|
||||
const go = document.getElementById('p4-iv1-go');
|
||||
const hide = document.getElementById('p4-iv1-hide');
|
||||
const seen = new Set();
|
||||
function show(){
|
||||
const k = +sl.value; idx.textContent = k;
|
||||
const t = T[k-1];
|
||||
bEl.innerHTML = '$' + t.before + '$';
|
||||
aEl.innerHTML = '<div style="font-size:.9rem;color:var(--muted);margin-bottom:6px">'+t.note+'</div>$' + t.before + ' \\;=\\; ' + t.steps + ' \\;=\\; ' + t.after + '$';
|
||||
aEl.style.display = 'none';
|
||||
renderMath(bEl);
|
||||
seen.add(k);
|
||||
if(seen.size === T.length && !seen.has('done')){ addXp(10,'p4-iv1'); bumpProgress('p4', 15); seen.add('done'); }
|
||||
}
|
||||
sl.addEventListener('input', show);
|
||||
go.addEventListener('click', ()=>{ aEl.style.display = 'block'; renderMath(aEl); });
|
||||
hide.addEventListener('click', ()=>{ aEl.style.display = 'none'; });
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV2 — Деление калькулятор */
|
||||
(function(){
|
||||
const aI = document.getElementById('p4-iv2-a');
|
||||
const bI = document.getElementById('p4-iv2-b');
|
||||
const cI = document.getElementById('p4-iv2-c');
|
||||
const dI = document.getElementById('p4-iv2-d');
|
||||
const out= document.getElementById('p4-iv2-out');
|
||||
const fb = document.getElementById('p4-iv2-fb');
|
||||
const go = document.getElementById('p4-iv2-go');
|
||||
let solved = 0;
|
||||
function calc(){
|
||||
const a = parseInt(aI.value,10), b = parseInt(bI.value,10),
|
||||
c = parseInt(cI.value,10), d = parseInt(dI.value,10);
|
||||
if([a,b,c,d].some(v => isNaN(v))){ feedback(fb, false, '✗ Введи 4 целых числа.'); return; }
|
||||
if(b === 0 || c === 0 || d === 0){ feedback(fb, false, '✗ $b$, $c$, $d$ не должны быть равны $0$.'); return; }
|
||||
const num = a * d;
|
||||
const den = b * c;
|
||||
const g = gcd(Math.abs(num), Math.abs(den));
|
||||
let n2 = num/g, d2 = den/g;
|
||||
if(d2 < 0){ n2 = -n2; d2 = -d2; }
|
||||
let resHtml;
|
||||
if(d2 === 1) resHtml = '$\\dfrac{'+a+'}{'+b+'} : \\dfrac{'+c+'}{'+d+'} = \\dfrac{'+a+'}{'+b+'} \\cdot \\dfrac{'+d+'}{'+c+'} = \\dfrac{'+num+'}{'+den+'} = '+n2+'$';
|
||||
else if(g === 1) resHtml = '$\\dfrac{'+a+'}{'+b+'} : \\dfrac{'+c+'}{'+d+'} = \\dfrac{'+a+'}{'+b+'} \\cdot \\dfrac{'+d+'}{'+c+'} = \\dfrac{'+num+'}{'+den+'}$ (несократимо)';
|
||||
else resHtml = '$\\dfrac{'+a+'}{'+b+'} : \\dfrac{'+c+'}{'+d+'} = \\dfrac{'+a+'}{'+b+'} \\cdot \\dfrac{'+d+'}{'+c+'} = \\dfrac{'+num+'}{'+den+'} = \\dfrac{'+n2+'}{'+d2+'}$';
|
||||
out.innerHTML = resHtml;
|
||||
renderMath(out);
|
||||
feedback(fb, true, '✓ Готово! +10 XP');
|
||||
solved++;
|
||||
if(solved === 1){ addXp(10,'p4-iv2'); bumpProgress('p4', 15); }
|
||||
}
|
||||
go.addEventListener('click', calc);
|
||||
calc();
|
||||
})();
|
||||
|
||||
/* IV3 — Верно/Ошибка */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ expr:'$\\dfrac{x}{2} \\cdot \\dfrac{3}{y} = \\dfrac{3x}{2y}$', ok:true, why:'умножили числители и знаменатели' },
|
||||
{ expr:'$\\dfrac{a}{b} : \\dfrac{c}{d} = \\dfrac{ad}{bc}$', ok:true, why:'это правило деления (умножение на обратную)' },
|
||||
{ expr:'$\\dfrac{a}{b} \\cdot \\dfrac{c}{d} = \\dfrac{a+c}{b+d}$', ok:false, why:'при умножении числители <b>перемножаются</b>, а не складываются' },
|
||||
{ expr:'$\\dfrac{2}{x} \\cdot \\dfrac{x}{2} = 1$', ok:true, why:'сократили $2x$ в числителе и $2x$ в знаменателе' },
|
||||
{ expr:'$\\dfrac{a}{b} : \\dfrac{c}{d} = \\dfrac{a}{b} \\cdot \\dfrac{c}{d}$', ok:false, why:'нужно умножать на <b>обратную</b> дробь: $\\dfrac{d}{c}$, а не $\\dfrac{c}{d}$' },
|
||||
{ expr:'$\\left(\\dfrac{2}{x}\\right)^2 = \\dfrac{2}{x^2}$', ok:false, why:'числитель тоже возводится в степень: правильно $\\dfrac{4}{x^2}$' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p4-iv3-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
if(score === Q.length){ addXp(15,'p4-iv3'); bumpProgress('p4', 25); }
|
||||
else if(score >= Q.length - 2){ addXp(8,'p4-iv3'); bumpProgress('p4', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p4-iv3-i').textContent = (i+1);
|
||||
document.getElementById('p4-iv3-s').textContent = score;
|
||||
document.getElementById('p4-iv3-q').innerHTML = Q[i].expr;
|
||||
renderMath(document.getElementById('p4-iv3-q'));
|
||||
document.getElementById('p4-iv3-fb').style.display = 'none';
|
||||
}
|
||||
function answer(isOk){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p4-iv3-fb');
|
||||
if(isOk === Q[i].ok){ score++; feedback(fb, true, '✓ Верно! '+Q[i].why+'. Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. '+Q[i].why+'. Дальше ▶');
|
||||
document.getElementById('p4-iv3-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1300);
|
||||
}
|
||||
document.getElementById('p4-iv3-ok').addEventListener('click', ()=>answer(true));
|
||||
document.getElementById('p4-iv3-err').addEventListener('click', ()=>answer(false));
|
||||
show();
|
||||
})();
|
||||
|
||||
/* IV4 — Тренажёр умножения/деления */
|
||||
(function(){
|
||||
const Q = [
|
||||
{ q:'$\\dfrac{3}{4} \\cdot \\dfrac{8}{9}$', ans:2, prompt:'числитель =', hint:'$=\\dfrac{24}{36} = \\dfrac{2}{3}$', res:'\\dfrac{2}{3}' },
|
||||
{ q:'$\\dfrac{x}{2} \\cdot \\dfrac{4}{x^2}$', ans:1, prompt:'показатель x в знам. =', hint:'$=\\dfrac{4x}{2x^2} = \\dfrac{2}{x}$', res:'\\dfrac{2}{x}' },
|
||||
{ q:'$\\dfrac{6}{a} : \\dfrac{2}{a}$', ans:3, prompt:'число =', hint:'$=\\dfrac{6}{a} \\cdot \\dfrac{a}{2} = \\dfrac{6a}{2a} = 3$', res:'3' },
|
||||
{ q:'$\\dfrac{5}{x+1} \\cdot \\dfrac{x+1}{10}$', ans:2, prompt:'знаменатель =', hint:'сократили $(x+1)$ и $5$: $\\dfrac{1}{2}$', res:'\\dfrac{1}{2}' },
|
||||
{ q:'$\\left(\\dfrac{3}{x}\\right)^2$', ans:9, prompt:'числитель =', hint:'$=\\dfrac{3^2}{x^2} = \\dfrac{9}{x^2}$', res:'\\dfrac{9}{x^2}' },
|
||||
{ q:'$\\dfrac{a^2}{b} : \\dfrac{a}{b^2}$', ans:1, prompt:'показатель a в ответе =', hint:'$=\\dfrac{a^2}{b} \\cdot \\dfrac{b^2}{a} = \\dfrac{a^2 b^2}{ab} = ab$ — у $a$ степень $1$', res:'ab' },
|
||||
];
|
||||
let i = 0, score = 0;
|
||||
function show(){
|
||||
if(i >= Q.length){
|
||||
document.getElementById('p4-iv4-q').innerHTML = '<b>Готово!</b> Результат: ' + score + ' / ' + Q.length;
|
||||
document.getElementById('p4-iv4-prompt').textContent = 'ответ =';
|
||||
if(score === Q.length){ addXp(15,'p4-iv4'); bumpProgress('p4', 25); }
|
||||
else if(score >= 4){ addXp(8,'p4-iv4'); bumpProgress('p4', 15); }
|
||||
return;
|
||||
}
|
||||
document.getElementById('p4-iv4-i').textContent = (i+1);
|
||||
document.getElementById('p4-iv4-s').textContent = score;
|
||||
document.getElementById('p4-iv4-q').innerHTML = 'Вычисли: ' + Q[i].q;
|
||||
document.getElementById('p4-iv4-prompt').textContent = Q[i].prompt;
|
||||
document.getElementById('p4-iv4-ans').value = '';
|
||||
renderMath(document.getElementById('p4-iv4-q'));
|
||||
document.getElementById('p4-iv4-fb').style.display = 'none';
|
||||
}
|
||||
function go(){
|
||||
if(i >= Q.length) return;
|
||||
const fb = document.getElementById('p4-iv4-fb');
|
||||
const ans = parseInt(document.getElementById('p4-iv4-ans').value, 10);
|
||||
if(isNaN(ans)){ feedback(fb, false, '✗ Введи целое число.'); return; }
|
||||
if(ans === Q[i].ans){ score++; feedback(fb, true, '✓ Верно! Ответ: $' + Q[i].res + '$ ('+Q[i].hint+'). Дальше ▶'); }
|
||||
else feedback(fb, false, '✗ Неверно. Должно быть $' + Q[i].ans + '$. Ответ: $' + Q[i].res + '$ ('+Q[i].hint+'). Дальше ▶');
|
||||
document.getElementById('p4-iv4-s').textContent = score;
|
||||
i++;
|
||||
setTimeout(show, 1400);
|
||||
}
|
||||
document.getElementById('p4-iv4-go').addEventListener('click', go);
|
||||
document.getElementById('p4-iv4-ans').addEventListener('keydown', e=>{ if(e.key === 'Enter') go(); });
|
||||
document.getElementById('p4-iv4-start').addEventListener('click', ()=>{ i=0; score=0; show(); });
|
||||
show();
|
||||
})();
|
||||
|
||||
wireReadBtn('p4');
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user