From cccbb641597aaef14e6c5c0012c4fdd09232770e Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Fri, 29 May 2026 08:08:46 +0300 Subject: [PATCH] =?UTF-8?q?feat(alg9=20ch1=20wave2):=20=C2=A73=20=C2=AB?= =?UTF-8?q?=D0=A1=D0=BB=D0=BE=D0=B6=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B8=20?= =?UTF-8?q?=D0=B2=D1=8B=D1=87=D0=B8=D1=82=D0=B0=D0=BD=D0=B8=D0=B5=C2=BB=20?= =?UTF-8?q?+=20=C2=A74=20=C2=AB=D0=A3=D0=BC=D0=BD=D0=BE=D0=B6=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=B8=20=D0=B4=D0=B5=D0=BB=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=C2=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/textbooks/algebra_9_ch1.html | 530 ++++++++++++++++++++++++-- 1 file changed, 502 insertions(+), 28 deletions(-) diff --git a/frontend/textbooks/algebra_9_ch1.html b/frontend/textbooks/algebra_9_ch1.html index b1531c6..1b12907 100644 --- a/frontend/textbooks/algebra_9_ch1.html +++ b/frontend/textbooks/algebra_9_ch1.html @@ -993,38 +993,512 @@ function buildP2(){ } function buildP3(){ - const root = document.getElementById('p3-body'); - root.innerHTML = ` -
-
- ${ICONS.theory} - В разработке - § 3 -
-
-

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

-

Раздел Phase 1.

-
-
` + secNav('p2', 'p4') + readButton('p3'); - renderMath(root); + const box = document.getElementById('p3-body'); + let html = ''; + + html += makeCard('theory', 'С одинаковыми знаменателями', '3.1', ` +

Чтобы сложить (или вычесть) рациональные дроби с одинаковыми знаменателями, надо сложить (вычесть) их числители, а знаменатель оставить прежним:

+ \\[\\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.\\] +

Примеры:

+ +
Часто допускаемая ошибка
+ При вычитании всегда заключай числитель вычитаемой дроби в скобки: $\\dfrac{A}{C} - \\dfrac{B}{C} = \\dfrac{A - (B)}{C}$, иначе можно «потерять» минус и получить $A - B$ вместо $A - B_1 + B_2$. +
`); + + html += makeCard('rule', 'С разными знаменателями · Алгоритм', '3.2', ` +

Если знаменатели разные — приводим дроби к общему знаменателю.

+
    +
  1. Разложить каждый знаменатель на множители.
  2. +
  3. Найти НОЗ — наименьший общий знаменатель: произведение всех различных множителей, взятых в наивысших степенях.
  4. +
  5. Привести каждую дробь к НОЗ: умножить числитель и знаменатель на нужный дополнительный множитель.
  6. +
  7. Сложить/вычесть числители (знаменатель — НОЗ).
  8. +
  9. Сократить результат, если возможно.
  10. +
+

Пример НОЗ:

+ `); + + html += makeCard('example', 'Примеры пошагово', '3.3', ` +

Пример 1. $\\dfrac{1}{x-2} + \\dfrac{1}{x+2}$. НОЗ $= (x-2)(x+2) = x^2 - 4$.

+ \\[\\dfrac{1}{x-2} + \\dfrac{1}{x+2} = \\dfrac{(x+2) + (x-2)}{(x-2)(x+2)} = \\dfrac{2x}{x^2-4}.\\] +

Пример 2. $\\dfrac{2}{a} - \\dfrac{3}{a^2}$. НОЗ $= a^2$. Дополнительный множитель для $\\dfrac{2}{a}$ равен $a$:

+ \\[\\dfrac{2}{a} - \\dfrac{3}{a^2} = \\dfrac{2a}{a^2} - \\dfrac{3}{a^2} = \\dfrac{2a - 3}{a^2}.\\] +

Пример 3 (с сокращением). $\\dfrac{1}{x-1} - \\dfrac{1}{x+1} = \\dfrac{(x+1) - (x-1)}{(x-1)(x+1)} = \\dfrac{2}{x^2-1}.$

`); + + /* INTERACTIVE 1 — Конструктор НОЗ */ + html += `
+
ИНТЕРАКТИВ 1
Конструктор НОЗ
+
Выбери пару знаменателей — увидишь разложение каждого, НОЗ и дополнительные множители.
+
+ +
+
+
+ + +
+ +
`; + + /* INTERACTIVE 2 — Калькулятор сложения */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор $\\dfrac{A}{C} \\pm \\dfrac{B}{C}$
+
Введи целые числители $A$ и $B$, выбери знак и знаменатель $C$ — получишь результат.
+
+ $A =$ + + + $B =$ + + над $C =$ + + +
+
+ +
`; + + /* INTERACTIVE 3 — DnD-сортер: какой НОЗ? */ + html += `
+
ИНТЕРАКТИВ 3
Какой НОЗ?
+
Перетащи каждую пару знаменателей в нужный ящик: тип НОЗ.
+
6 пар — 3 типа НОЗ
+
+
+
Произведение знаменателей
+
Один из знаменателей
+
Просто число
+
+
+ +
`; + + /* INTERACTIVE 4 — Тренажёр сложения/вычитания */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр сложения и вычитания
+
Реши пример и введи число, которое спрашивают в подсказке.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ ответ = + + + +
+ +
`; + + 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 = '
Разложение: $'+p.d1+' = '+p.fact1+'$,  $'+p.d2+' = '+p.fact2+'$
' + + '
НОЗ $= '+p.lcm+'$
' + + '
Доп. множители: к $\\dfrac{?}{'+p.d1+'}$ → $'+p.add1+'$; к $\\dfrac{?}{'+p.d2+'}$ → $'+p.add2+'$
'; + 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 = 'Готово! Результат: ' + 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 = ` -
-
- ${ICONS.theory} - В разработке - § 4 -
-
-

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

-

Раздел Phase 1.

-
-
` + secNav('p3', 'p5') + readButton('p4'); - renderMath(root); + const box = document.getElementById('p4-body'); + let html = ''; + + html += makeCard('theory', 'Умножение дробей', '4.1', ` +

Чтобы умножить две рациональные дроби, надо перемножить их числители и перемножить знаменатели:

+ \\[\\dfrac{A}{B} \\cdot \\dfrac{C}{D} = \\dfrac{A \\cdot C}{B \\cdot D}, \\quad B \\ne 0,\\ D \\ne 0.\\] +

Чаще удобно сократить общие множители до умножения — это упрощает вычисления.

+

Пример: $\\dfrac{2x}{3} \\cdot \\dfrac{5}{x^2} = \\dfrac{2x \\cdot 5}{3 \\cdot x^2} = \\dfrac{10x}{3x^2} = \\dfrac{10}{3x}$ — сократили $x$.

+
Можно ли «крест-накрест»?
+ При умножении сокращать можно любой множитель числителя с любым множителем знаменателя (даже «крест-накрест»): $\\dfrac{a}{b} \\cdot \\dfrac{b}{c} = \\dfrac{a}{c}$, $b$ ушло. +
`); + + html += makeCard('rule', 'Деление дробей · Правило', '4.2', ` +

Чтобы разделить одну рациональную дробь на другую, надо первую дробь умножить на обратную ко второй:

+ \\[\\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.\\] +

Обратная дробь к $\\dfrac{C}{D}$ — это $\\dfrac{D}{C}$ (числитель и знаменатель меняются местами).

+

Условие $C \\ne 0$ возникает потому, что мы делим на дробь $\\dfrac{C}{D}$, а на ноль делить нельзя.

+

Запомни: деление = умножение на перевёрнутую дробь. После этого работаем как с обычным умножением.

`); + + html += makeCard('example', 'Возведение дроби в степень', '4.3', ` +

Чтобы возвести дробь в натуральную степень $n$, надо возвести в эту степень и числитель, и знаменатель:

+ \\[\\left(\\dfrac{A}{B}\\right)^n = \\dfrac{A^n}{B^n}, \\quad B \\ne 0.\\] +

Примеры:

+ `); + + /* INTERACTIVE 1 — Умножение с подсветкой */ + html += `
+
ИНТЕРАКТИВ 1
Умножение с подсветкой
+
Выбери задачу — увидишь произведение дробей. Нажми «Показать шаги», чтобы увидеть сокращение.
+
+ +
+
+
+ + +
+ +
`; + + /* INTERACTIVE 2 — Калькулятор деления a/b : c/d */ + html += `
+
ИНТЕРАКТИВ 2
Калькулятор деления $\\dfrac{a}{b} : \\dfrac{c}{d}$
+
Введи целые $a, b, c, d$ — увидишь преобразование к умножению и упрощённый результат.
+
+ $a =$ + $b =$ + $c =$ + $d =$ + +
+
+ +
`; + + /* INTERACTIVE 3 — Найди ошибку */ + html += `
+
ИНТЕРАКТИВ 3
Верно или ошибка?
+
Реши каждое преобразование: верно оно или нет. 6 заданий.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ + +
+ +
`; + + /* INTERACTIVE 4 — Тренажёр умножения и деления */ + html += `
+
ИНТЕРАКТИВ 4
Тренажёр умножения и деления
+
Вычисли и введи число, которое спрашивают в подсказке.
+
Задача 1 / 6Очки: 0 / 6
+
+
+ ответ = + + + +
+ +
`; + + 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 = '
'+t.note+'
$' + 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:'при умножении числители перемножаются, а не складываются' }, + { 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:'нужно умножать на обратную дробь: $\\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 = 'Готово! Результат: ' + 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 = 'Готово! Результат: ' + 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'); }