diff --git a/backend/tests/math5-page.test.js b/backend/tests/math5-page.test.js index 3500727..54a2a4c 100644 --- a/backend/tests/math5-page.test.js +++ b/backend/tests/math5-page.test.js @@ -112,6 +112,10 @@ test('ch1: §1 «как решать задачу», §2 «разрядная т assert.ok(doc.querySelector('#p11-fig svg circle'), '§11: точки-группы с остатком'); win.goTo('p12'); await wait(80); assert.ok(doc.querySelector('#p12-fig'), '§12: делители-чипсы (НОД)'); + win.goTo('p13'); await wait(80); + assert.ok(doc.querySelector('#p13-out'), '§13: чекер делимости'); + win.goTo('p14'); await wait(80); + assert.equal(doc.querySelectorAll('#p14-grid [data-n]').length, 29, '§14: решето 2..30'); win.goTo('final'); await wait(80); assert.ok(doc.querySelector('#fin-go'), 'финал: арена боссов'); win.bumpProgress('final', 100); await wait(20); diff --git a/frontend/textbooks/math_5_ch1.html b/frontend/textbooks/math_5_ch1.html index f632a6d..4527eb4 100644 --- a/frontend/textbooks/math_5_ch1.html +++ b/frontend/textbooks/math_5_ch1.html @@ -1049,6 +1049,145 @@ function buildP12(){ })(); } +/* ===================== § 13. ПРИЗНАКИ ДЕЛИМОСТИ ===================== */ +function buildP13(){ + var box=document.getElementById('p13-body'); var h=''; + h+=makeCard('oral','Где это в жизни','13.0', + '

Иногда нужно быстро понять: разделится ли число нацело — не выполняя деления. Можно ли $87$ конфет раздать поровну троим? А $90$? Признаки делимости дают ответ за секунду.

'); + h+=makeCard('rule','Признаки делимости','13.1', + '

На 2 — если последняя цифра чётная ($0,2,4,6,8$).

' + +'

На 5 — если последняя цифра $0$ или $5$.

' + +'

На 10 — если последняя цифра $0$.

' + +'

На 3 — если сумма цифр делится на $3$.

' + +'

На 9 — если сумма цифр делится на $9$.

' + +'

На 4 — если число из двух последних цифр делится на $4$.

'); + h+=makeCard('example','Примеры','13.2', + '

$540$ делится на $2,5,10$ (оканчивается на $0$) и на $3$ (сумма цифр $5+4+0=9$).

' + +'

$123$ делится на $3$ ($1+2+3=6$), но не на $2$ и не на $9$.

'); + h+=makeCard('example','Разбор по шагам','13.3', + '

Проверим, делится ли $5\\,814$ на $2$, $3$ и $9$.

' + +'
    ' + +'
  1. На $2$: последняя цифра $4$ — чётная. Делится.
  2. ' + +'
  3. Сумма цифр: $5+8+1+4=18$.
  4. ' + +'
  5. На $3$: $18$ делится на $3$. Делится.
  6. ' + +'
  7. На $9$: $18$ делится на $9$. Делится.
  8. ' + +'
'); + h+=makeCard('theory','А знаешь ли ты?','13.4', + '

Есть признак и для $11$: складывают цифры через одну и вычитают суммы. Если разность делится на $11$ — и число делится. Например, $2\\,728$: $(8+7)-(2+2)=11$ — делится на $11$!

'); + h+='
Интерактив 1
Проверка делимости
' + +'
Введи число — увидишь, на что оно делится, и почему.
' + +'
' + +'
'; + h+='
Интерактив 2
Делится ли нацело?
' + +'
Используй признак делимости и ответь «да» или «нет».
' + +'
Вопрос 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+=secNav('p12','p14')+readBtn('p13'); + box.innerHTML=h; renderMath(box); + + (function(){ + function check(){ + var raw=(document.getElementById('p13-in').value||'').replace(/\D/g,''); if(!raw)raw='0'; var n=parseInt(raw,10); + var ds=raw.split('').reduce(function(a,c){return a+(+c);},0); + var rules=[ + ['на 2', n%2===0, 'последняя цифра '+raw[raw.length-1]], + ['на 3', n%3===0, 'сумма цифр '+ds], + ['на 4', n%4===0, 'две последние: '+raw.slice(-2)], + ['на 5', n%5===0, 'последняя цифра '+raw[raw.length-1]], + ['на 9', n%9===0, 'сумма цифр '+ds], + ['на 10', n%10===0, 'последняя цифра '+raw[raw.length-1]] + ]; + var s='
'; + rules.forEach(function(r){ s+='
'+(r[1]?'✓ ':'✗ ')+r[0]+'
'+r[2]+'
'; }); + document.getElementById('p13-out').innerHTML=s+'
'; + } + document.getElementById('p13-chk').addEventListener('click',check); + document.getElementById('p13-in').addEventListener('keydown',function(e){ if(e.key==='Enter')check(); }); + check(); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var d=_pick([2,3,5,9,4,10]), n=_ri(100,999); cur={n:n,d:d,yes:n%d===0}; } + function show(){ if(i>=6){ document.getElementById('p13-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p13-iv2');bumpProgress('p13',30);}else if(score>=3){addXp(8,'p13-iv2');bumpProgress('p13',16);} return; } + gen(); document.getElementById('p13-i').textContent=i+1; + document.getElementById('p13-q').innerHTML='Делится ли $'+cur.n+'$ нацело на $'+cur.d+'$?'; renderMath(document.getElementById('p13-q')); + document.getElementById('p13-fb').style.display='none'; } + function ans(yn){ if(i>=6)return; var fb=document.getElementById('p13-fb'); + if((yn===1)===cur.yes){ score++; feedback(fb,true,'✓ Верно! '+cur.n+(cur.yes?' делится':' не делится')+' на '+cur.d+'.'); } else feedback(fb,false,'✗ Нет. '+cur.n+(cur.yes?' делится':' не делится')+' на '+cur.d+'.'); + document.getElementById('p13-s').textContent=score; i++; setTimeout(show,1200); } + document.querySelectorAll('#p13-iv2 [data-yn]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-yn')); }); }); + show(); + })(); +} + +/* ===================== § 14. ПРОСТЫЕ И СОСТАВНЫЕ ЧИСЛА ===================== */ +function buildP14(){ + var box=document.getElementById('p14-body'); var h=''; + h+=makeCard('oral','Где это в жизни','14.0', + '

Простые числа — «кирпичики», из которых умножением складываются все остальные числа. На свойствах простых чисел держится защита банковских карт и переписки в интернете: огромное число легко перемножить, но почти невозможно разложить обратно.

'); + h+=makeCard('theory','Простые и составные','14.1', + '

Простое число имеет ровно два делителя: $1$ и само себя ($2,3,5,7,11,13,\\dots$).

' + +'

Составное число имеет больше двух делителей ($4,6,8,9,\\dots$).

' + +'

Число $1$ — ни простое, ни составное (у него один делитель). $2$ — единственное чётное простое.

'); + h+=makeCard('rule','Разложение на простые множители','14.2', + '

Любое составное число можно представить как произведение простых множителей — единственным образом. Делят на наименьшие простые: $2,3,5,7,\\dots$

'); + h+=makeCard('example','Разбор по шагам','14.3', + '

Разложим $60$ на простые множители.

' + +'
    ' + +'
  1. $60:2=30$.
  2. ' + +'
  3. $30:2=15$.
  4. ' + +'
  5. $15:3=5$.
  6. ' + +'
  7. $5$ — простое. Итог: $60=2\\cdot2\\cdot3\\cdot5=2^2\\cdot3\\cdot5$.
  8. ' + +'
'); + h+=makeCard('theory','А знаешь ли ты?','14.4', + '

Простых чисел бесконечно много — это доказал ещё Евклид. А самое большое известное простое число содержит более $41$ миллиона цифр! Его нашли в $2024$ году с помощью тысяч компьютеров по всему миру.

'); + h+='
Интерактив 1
Решето Эратосфена
' + +'
Нажми на все простые числа от 2 до 30, затем проверь себя.
' + +'
' + +'
' + +'
'; + h+='
Интерактив 2
Простое или составное?
' + +'
Определи, простое число или составное.
' + +'
Вопрос 1 / 6Очки: 0 / 6
' + +'
' + +'
' + +'
'; + h+=secNav('p13','p15')+readBtn('p14'); + box.innerHTML=h; renderMath(box); + + function isPrime(n){ if(n<2)return false; for(var k=2;k*k<=n;k++)if(n%k===0)return false; return true; } + + (function(){ + var sel={}; + var grid=document.getElementById('p14-grid'),html=''; + for(var n=2;n<=30;n++) html+=''; + grid.innerHTML=html; + grid.querySelectorAll('[data-n]').forEach(function(b){ b.addEventListener('click',function(){ var n=+b.getAttribute('data-n'); if(sel[n]){ delete sel[n]; b.classList.remove('primary'); } else { sel[n]=1; b.classList.add('primary'); } }); }); + document.getElementById('p14-chk').addEventListener('click',function(){ var fb=document.getElementById('p14-fb'),ok=0,bad=0,miss=0; + for(var n=2;n<=30;n++){ var p=isPrime(n),s=!!sel[n]; if(p&&s)ok++; else if(!p&&s)bad++; else if(p&&!s)miss++; } + if(bad===0&&miss===0){ feedback(fb,true,'✓ Идеально! Все простые числа до 30 найдены. +15 XP'); addXp(15,'p14-iv1'); bumpProgress('p14',35); } + else feedback(fb,false,'✗ Верных: '+ok+'. Лишних: '+bad+', пропущено: '+miss+'. Простые до 30: 2,3,5,7,11,13,17,19,23,29.'); }); + document.getElementById('p14-rst').addEventListener('click',function(){ sel={}; grid.querySelectorAll('[data-n]').forEach(function(b){ b.classList.remove('primary'); }); document.getElementById('p14-fb').style.display='none'; }); + })(); + + (function(){ + var i=0,score=0,cur=null; + function gen(){ var n; if(_ri(0,1)===0){ var pr=[2,3,5,7,11,13,17,19,23,29,31,37,41,43]; n=_pick(pr); } else { n=_ri(4,49); while(isPrime(n))n=_ri(4,49); } cur={n:n,prime:isPrime(n)}; } + function show(){ if(i>=6){ document.getElementById('p14-q').innerHTML='Готово! '+score+' / 6'; if(score>=5){addXp(15,'p14-iv2');bumpProgress('p14',30);}else if(score>=3){addXp(8,'p14-iv2');bumpProgress('p14',16);} return; } + gen(); document.getElementById('p14-i').textContent=i+1; + document.getElementById('p14-q').innerHTML='Число $'+cur.n+'$ — простое или составное?'; renderMath(document.getElementById('p14-q')); + document.getElementById('p14-qfb').style.display='none'; } + function ans(p){ if(i>=6)return; var fb=document.getElementById('p14-qfb'); + if((p===1)===cur.prime){ score++; feedback(fb,true,'✓ Верно! '+cur.n+' — '+(cur.prime?'простое':'составное')+'.'); } else feedback(fb,false,'✗ Нет. '+cur.n+' — '+(cur.prime?'простое':'составное')+'.'); + document.getElementById('p14-s').textContent=score; i++; setTimeout(show,1200); } + document.querySelectorAll('#p14-iv2 [data-p]').forEach(function(b){ b.addEventListener('click',function(){ ans(+b.getAttribute('data-p')); }); }); + show(); + })(); +} + /* ===================== ДАННЫЕ САЙДБАРА / ГЛОССАРИЯ ===================== */ var SIDEBARS = { p1:{ title:'Шпаргалка § 1', rows:[ @@ -1112,6 +1251,16 @@ var SIDEBARS = { ['Кратное','делится на число нацело'], ['НОД','наибольший общий делитель'], ['НОК','наименьшее общее кратное'] ]}, + p13:{ title:'Шпаргалка § 13', rows:[ + ['на 2','последняя цифра чётная'], + ['на 5 / 10','оканчивается на 0/5 · на 0'], + ['на 3 / 9','сумма цифр делится на 3 / 9'], + ['на 4','две последние делятся на 4'] ]}, + p14:{ title:'Шпаргалка § 14', rows:[ + ['Простое','ровно 2 делителя'], + ['Составное','больше 2 делителей'], + ['1','ни простое, ни составное'], + ['Разложение','$60=2^2\\cdot3\\cdot5$'] ]}, final:{ title:'Финал главы 1', rows:[ ['5 боссов','разряды, округление, действия, степень'], ['Победа','4 из 5 и больше'], @@ -1131,7 +1280,7 @@ var GLOSSARY = [ { term:'разряд', def:'Место цифры в записи числа: единицы, десятки, сотни и т. д.', sec:'p2', aliases:['разряд','разряда','разряде','разряды','разрядов'] }, { term:'класс', def:'Группа из трёх соседних разрядов: единицы, тысячи, миллионы.', sec:'p2', aliases:['класс','класса','классе','классы','классов'] } ]; -var BUILDERS = { p1:buildP1, p2:buildP2, p3:buildP3, p4:buildP4, p5:buildP5, p6:buildP6, p7:buildP7, p8:buildP8, p9:buildP9, p10:buildP10, p11:buildP11, p12:buildP12, final:buildFinal }; +var BUILDERS = { p1:buildP1, p2:buildP2, p3:buildP3, p4:buildP4, p5:buildP5, p6:buildP6, p7:buildP7, p8:buildP8, p9:buildP9, p10:buildP10, p11:buildP11, p12:buildP12, p13:buildP13, p14:buildP14, final:buildFinal }; Object.assign(window.M6, { sidebars:SIDEBARS, tips:TIPS, glossary:GLOSSARY, builders:BUILDERS });