Files
Learn_System/backend/scripts/seed_ctmath_ct2013_v1.js
T
Maxim Dolgolyov 0fb16ef85e content(ctmath): вариант 119 — ЦТ-2013 (А1–А18 + В1–В12, 30 заданий)
Перенабор Вариант 1 из ЦТ2013.pdf, все 30 ответов сверены с официальной
таблицей (полное совпадение). Фигурные A2/A3/A6/A16 реконструированы с явными
описаниями (A2 — образующая=AD, A6 — порядок лучей→40°, A16 — сечение 12×6=72).
Все В-задания числовые (long нет). Без авторских ссылок. Дедуп-гейт 0,
KaTeX 30/30, DRY-RUN 30/30. VARIANT_LABEL: 119='ЦТ-2013'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-20 16:35:28 +03:00

349 lines
28 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/* ───────────────────────────────────────────────────────────────────────────
seed_ctmath_ct2013_v1.js
Чистый вариант-пробник для трека exam-prep `ctmath`.
Источник: Централизованное тестирование (ЦТ) по математике, 2013, Вариант 1.
Формат: Часть А = А1–А18, Часть В = В1–В12 (все В — числовые). Всего 30 заданий.
Перенабрано вручную в KaTeX по PDF: F:\!Рабочие\ЦТ\Математика\Математика\ЦТ-ЦЭ\2013\ЦТ2013.pdf
(ответы — отдельный файл «Ответы ЦТ 2013.pdf», столбец «Вариант 1»).
⚠️ ВСЕ 30 ответов решены самостоятельно и СВЕРЕНЫ с официальной таблицей — полное
совпадение, включая B3=75, B9=40, B10=6, B12=-5. variant=119. Прогнан через
дедуп-гейт (check_variant_dups.js) — без повторов с видимым пулом.
Реконструкции заданий-«с-картинкой» (смысл/ответ сохранены, авто-проверка):
• А2 (образующая цилиндра) → взаимное расположение точек дано в тексте (AD ⟂ основаниям → AD);
• А3 (точка на графике) → прямая задана как $y=13$, точки перечислены (T(-7;13));
• А6 (углы при развёрнутом угле) → порядок лучей задан явно (∠BOC=40°);
• А16 (сечение параллелепипеда) → размеры/угол 60° в тексте (сечение 12×6=72).
Без авторских ссылок (политика «все учебники наши»).
Идемпотентность: upsert по UNIQUE(exam_key, variant, task_idx).
Запуск:
node backend/scripts/seed_ctmath_ct2013_v1.js # DRY-RUN (по умолчанию)
node backend/scripts/seed_ctmath_ct2013_v1.js --apply # запись в БД
⚠️ Массовую запись в БД запускает ПОЛЬЗОВАТЕЛЬ вручную. Без --apply ничего не пишется.
─────────────────────────────────────────────────────────────────────────── */
const { DatabaseSync } = require('node:sqlite');
const path = require('path');
const APPLY = process.argv.includes('--apply');
const EXAM = 'ctmath';
const VARIANT = 119;
const N_TASKS = 30;
const PROV = 'ЦТ–2013, Вариант 1';
const R = String.raw;
const L = ['а', 'б', 'в', 'г', 'д'];
const mc = (...html) => html.map((h, i) => [L[i], h]);
/* ── 30 заданий ─────────────────────────────────────────────────────────── */
const TASKS = [
// ── Часть A: А1–А18 ──────────────────────────────────────────────────────
{ idx: 1, type: 'mc', topic: 'numbers', subtopic: 'num-real', diff: 1,
text: R`Среди чисел $\sqrt9$; $-9$; $\dfrac19$; $-0{,}9$; $9^{-1}$ выберите число, противоположное числу $9$.`,
opts: mc('$\sqrt9$', '$-9$', '$\dfrac19$', '$-0{,}9$', '$9^{-1}$'),
answer: 'б',
sol: R`Противоположное числу $9$ — это $-9$.` },
{ idx: 2, type: 'mc', topic: 'stereometry', subtopic: 'ster-rotation', diff: 1,
text: R`Прямой круговой цилиндр; $O$ и $O_1$ — центры верхнего и нижнего оснований. Точки $A$ и $B$ лежат на окружности верхнего основания, $C$ и $D$ — на окружности нижнего, причём $A$ находится точно над $D$ (отрезок $AD$ перпендикулярен основаниям). Образующей цилиндра является отрезок:`,
opts: mc('$DB$', '$DC$', '$DO_1$', '$OO_1$', '$AD$'),
answer: 'д',
sol: R`Образующая прямого цилиндра — отрезок поверхности, перпендикулярный основаниям и соединяющий соответствующие точки окружностей. Это отрезок $AD$ ($OO_1$ — ось, а не образующая).` },
{ idx: 3, type: 'mc', topic: 'functions', subtopic: 'fn-graphs', diff: 1,
text: R`Среди точек $B(13;0)$, $T(-7;13)$, $C\left(-\sqrt{13};\sqrt{13}\right)$, $O(0;0)$, $L(0;-13)$ выберите ту, которая принадлежит графику функции $y=13$.`,
opts: mc('$B$', '$T$', '$C$', '$O$', '$L$'),
answer: 'б',
sol: R`Графику $y=13$ принадлежат точки с ординатой $13$. Это $T(-7;13)$.` },
{ idx: 4, type: 'mc', topic: 'numbers', subtopic: 'num-fractions', diff: 2,
text: R`Найдите значение выражения $\left(2\tfrac{7}{12}-2\tfrac{17}{36}\right)\cdot2{,}7-0{,}4$.`,
opts: mc('$0{,}1$', '$-0{,}7$', '$-0{,}1$', '$0{,}3$', '$-1{,}5$'),
answer: 'в',
sol: R`$2\tfrac{7}{12}-2\tfrac{17}{36}=\tfrac{93-89}{36}=\tfrac{4}{36}=\tfrac19$. Тогда $\tfrac19\cdot2{,}7-0{,}4=0{,}3-0{,}4=-0{,}1$.` },
{ idx: 5, type: 'mc', topic: 'word-sequences', subtopic: 'word-problems', diff: 2,
text: R`Одно число меньше другого на $64$, что составляет $16\%$ большего числа. Найдите меньшее число.`,
opts: mc('$800$', '$470$', '$336$', '$464$', '$390$'),
answer: 'в',
sol: R`Большее число $=\dfrac{64}{0{,}16}=400$, меньшее $=400-64=336$.` },
{ idx: 6, type: 'mc', topic: 'planimetry', subtopic: 'plan-angles', diff: 2,
text: R`Угол $AOM$ — развёрнутый ($A$, $O$, $M$ на одной прямой). Лучи $OB$ и $OC$ проведены по одну сторону от прямой $AM$, причём луч $OB$ ближе к лучу $OA$. Известно, что $\angle AOC=107^\circ$, $\angle BOM=113^\circ$. Найдите величину угла $BOC$.`,
opts: mc('$73^\circ$', '$67^\circ$', '$17^\circ$', '$40^\circ$', '$23^\circ$'),
answer: 'г',
sol: R`$\angle AOB=180^\circ-\angle BOM=67^\circ$, поэтому $\angle BOC=\angle AOC-\angle AOB=107^\circ-67^\circ=40^\circ$.` },
{ idx: 7, type: 'mc', topic: 'stereometry', subtopic: 'ster-rotation', diff: 2,
text: R`Образующая конуса равна $26$ и наклонена к плоскости основания под углом $60^\circ$. Найдите площадь боковой поверхности конуса.`,
opts: mc('$338\pi$', '$338\sqrt3\,\pi$', '$169\pi$', '$260\sqrt3\,\pi$', '$676\pi$'),
answer: 'а',
sol: R`Радиус $r=l\cos60^\circ=26\cdot\tfrac12=13$. Боковая поверхность $=\pi r l=\pi\cdot13\cdot26=338\pi$.` },
{ idx: 8, type: 'mc', topic: 'numbers', subtopic: 'num-real', diff: 2,
text: R`Расположите числа $2{,}44$; $\dfrac{18}{7}$; $2{,}(4)$ в порядке возрастания.`,
opts: mc('$2{,}44;\ \dfrac{18}{7};\ 2{,}(4)$', '$2{,}44;\ 2{,}(4);\ \dfrac{18}{7}$', '$\dfrac{18}{7};\ 2{,}44;\ 2{,}(4)$', '$2{,}(4);\ \dfrac{18}{7};\ 2{,}44$', '$2{,}(4);\ 2{,}44;\ \dfrac{18}{7}$'),
answer: 'б',
sol: R`$2{,}44<2{,}(4)=2{,}444\ldots<\dfrac{18}{7}=2{,}571\ldots$, то есть $2{,}44;\ 2{,}(4);\ \dfrac{18}{7}$.` },
{ idx: 9, type: 'mc', topic: 'equations', subtopic: 'eq-quadratic', diff: 2,
text: R`Одна из сторон прямоугольника на $7$ см длиннее другой, а его площадь равна $78$ см². Уравнение, одним из корней которого является длина меньшей стороны прямоугольника, имеет вид:`,
opts: mc('$x^{2}-78x+7=0$', '$x^{2}-7x-78=0$', '$x^{2}+7x+78=0$', '$x^{2}+7x-78=0$', '$x^{2}+78x-7=0$'),
answer: 'г',
sol: R`Если меньшая сторона $x$, то $x(x+7)=78$, то есть $x^{2}+7x-78=0$.` },
{ idx: 10, type: 'mc', topic: 'planimetry', subtopic: 'plan-coordinates', diff: 2,
text: R`Точки $A(-3;3)$ и $B(4;1)$ — вершины квадрата $ABCD$. Периметр квадрата равен:`,
opts: mc('$4\sqrt{17}$', '$2\sqrt{53}$', '$18$', '$15$', '$4\sqrt{53}$'),
answer: 'д',
sol: R`$AB=\sqrt{(4+3)^{2}+(1-3)^{2}}=\sqrt{49+4}=\sqrt{53}$ — сторона квадрата. Периметр $=4\sqrt{53}$.` },
{ idx: 11, type: 'mc', topic: 'expressions', subtopic: 'expr-powers-roots', diff: 3,
text: R`Упростите выражение $\dfrac{11\sqrt{11}+5\sqrt5}{\sqrt{11}+\sqrt5}-\sqrt{55}+\dfrac{12\sqrt5}{\sqrt{11}-\sqrt5}$.`,
opts: mc('$\dfrac{1}{\sqrt{11}+\sqrt5}$', '$\sqrt{55}$', '$16$', '$26$', '$\dfrac{5}{\sqrt{11}-\sqrt5}$'),
answer: 'г',
sol: R`$\dfrac{(\sqrt{11})^{3}+(\sqrt5)^{3}}{\sqrt{11}+\sqrt5}=11-\sqrt{55}+5=16-\sqrt{55}$; $\dfrac{12\sqrt5}{\sqrt{11}-\sqrt5}=2\sqrt5(\sqrt{11}+\sqrt5)=2\sqrt{55}+10$. Сумма: $(16-\sqrt{55})-\sqrt{55}+(2\sqrt{55}+10)=26$.` },
{ idx: 12, type: 'mc', topic: 'equations', subtopic: 'eq-rational', diff: 2,
text: R`Решением неравенства $\dfrac{26}{3}-\dfrac{7x^{2}+4x}{7}>\dfrac{2-3x^{2}}{3}$ является промежуток:`,
opts: mc('$(14;+\infty)$', '$(-14;+\infty)$', '$\left(-\infty;\dfrac{1}{14}\right)$', '$(-\infty;14)$', '$\left(\dfrac{1}{14};+\infty\right)$'),
answer: 'г',
sol: R`Умножив на $21$: $182-3(7x^{2}+4x)>7(2-3x^{2})$, то есть $182-21x^{2}-12x>14-21x^{2}$, $182-12x>14$, $x<14$.` },
{ idx: 13, type: 'mc', topic: 'planimetry', subtopic: 'plan-quadrilaterals', diff: 2,
text: R`Найдите длину средней линии прямоугольной трапеции с острым углом $60^\circ$, у которой бóльшая боковая сторона и бóльшее основание равны $10$.`,
opts: mc('$5\sqrt3$', '$10\sqrt3$', '$15$', '$5$', '$7{,}5$'),
answer: 'д',
sol: R`Проекция наклонной боковой стороны на основание $=10\cos60^\circ=5$, поэтому меньшее основание $=10-5=5$. Средняя линия $=\dfrac{10+5}{2}=7{,}5$.` },
{ idx: 14, type: 'mc', topic: 'expressions', subtopic: 'expr-fractions', diff: 3,
text: R`Упростите выражение $\left(5+\dfrac{a^{2}+25c^{2}-b^{2}}{2ac}\right):(a+b+5c)\cdot2ac$.`,
opts: mc('$a+5c-b$', '$4a^{2}c^{2}$', '$5$', '$a+5c+b$', '$a-5c-b$'),
answer: 'а',
sol: R`$5+\dfrac{a^{2}+25c^{2}-b^{2}}{2ac}=\dfrac{(a+5c)^{2}-b^{2}}{2ac}=\dfrac{(a+5c-b)(a+5c+b)}{2ac}$. После деления на $(a+b+5c)$ и умножения на $2ac$ получаем $a+5c-b$.` },
{ idx: 15, type: 'mc', topic: 'equations', subtopic: 'eq-rational', diff: 2,
text: R`Найдите сумму целых решений неравенства $3(x-5)>(x-5)^{2}$.`,
opts: mc('$13$', '$9$', '$-13$', '$26$', '$-9$'),
answer: 'а',
sol: R`Пусть $u=x-5$: $3u>u^{2}$, $u(u-3)<0$, $0<u<3$, значит $5<x<8$. Целые $6$ и $7$, их сумма $13$.` },
{ idx: 16, type: 'mc', topic: 'stereometry', subtopic: 'ster-polyhedra', diff: 3,
text: R`$ABCDA_1B_1C_1D_1$ — прямоугольный параллелепипед, $AB=12$, $AD=3$. Через середины рёбер $AA_1$ и $BB_1$ проведена плоскость, составляющая угол $60^\circ$ с плоскостью основания $ABCD$. Найдите площадь сечения параллелепипеда этой плоскостью.`,
opts: mc('$72$', '$36\sqrt3$', '$36$', '$18$', '$36\sqrt2$'),
answer: 'а',
sol: R`Сечение — параллелограмм; одна сторона равна $AB=12$, другая проходит через всю глубину $AD=3$ под углом $60^\circ$: её длина $=\dfrac{3}{\cos60^\circ}=6$. Площадь $=12\cdot6=72$.` },
{ idx: 17, type: 'mc', topic: 'trigonometry', subtopic: 'trig-identities', diff: 3,
text: R`Сумма наибольшего и наименьшего значений функции $y=(3\sin2x+3\cos2x)^{2}$ равна:`,
opts: mc('$8$', '$9$', '$18$', '$36$', '$3$'),
answer: 'в',
sol: R`$y=9(\sin2x+\cos2x)^{2}=9(1+\sin4x)$. Так как $\sin4x\in[-1;1]$, то $y\in[0;18]$. Сумма $0+18=18$.` },
{ idx: 18, type: 'mc', topic: 'equations', subtopic: 'eq-logarithmic', diff: 3,
text: R`Корень уравнения $\log_{1{,}6}\dfrac{9-4x}{3x-11}+\log_{1{,}6}\big((9-4x)(3x-11)\big)=0$ (или их сумма, если корней несколько) принадлежит промежутку:`,
opts: mc('$[0;1)$', '$[1;2)$', '$(2;3]$', '$(3;4]$', '$[-1;0)$'),
answer: 'в',
sol: R`Сумма логарифмов равна $\log_{1{,}6}(9-4x)^{2}=0$, поэтому $(9-4x)^{2}=1$, $x=2$ или $x=2{,}5$. Из условия положительности обоих аргументов остаётся $x=2{,}5\in(2;3]$.` },
// ── Часть B: В1–В12 (все числовые) ───────────────────────────────────────
{ idx: 19, type: 'open', topic: 'word-sequences', subtopic: 'word-problems', diff: 3,
text: R`Автомобиль проехал некоторое расстояние, израсходовав $21$ л топлива; расход составил $9$ л на $100$ км пробега. Затем расход топлива вырос до $12$ л на $100$ км. Сколько литров топлива понадобится автомобилю, чтобы проехать такое же расстояние?`,
answer: '28',
sol: R`Расстояние $=\dfrac{21}{9}\cdot100$ км. При расходе $12$ л/$100$ км нужно $\dfrac{21}{9}\cdot12=28$ л.` },
{ idx: 20, type: 'open', topic: 'equations', subtopic: 'eq-irrational', diff: 3,
text: R`Решите уравнение $\sqrt{x-5}-\sqrt{(x-5)(x+2)}=0$. В ответ запишите сумму его корней (корень, если он один).`,
answer: '5',
sol: R`ОДЗ: $x\ge5$. $\sqrt{x-5}\,\big(1-\sqrt{x+2}\big)=0$ даёт $x=5$ (второй множитель при $x\ge5$ не равен нулю). Единственный корень $5$.` },
{ idx: 21, type: 'open', topic: 'planimetry', subtopic: 'plan-triangles', diff: 3,
text: R`Основание остроугольного равнобедренного треугольника равно $10$, а синус противолежащего угла равен $0{,}6$. Найдите площадь треугольника.`,
answer: '75',
sol: R`Острый противолежащий угол $\alpha$: $\sin\alpha=0{,}6$, $\cos\alpha=0{,}8$. По теореме косинусов $10^{2}=2b^{2}(1-\cos\alpha)=0{,}4b^{2}$, $b^{2}=250$. Площадь $=\tfrac12 b^{2}\sin\alpha=\tfrac12\cdot250\cdot0{,}6=75$.` },
{ idx: 22, type: 'open', topic: 'equations', subtopic: 'eq-systems', diff: 4,
text: R`Пусть $(x;y)$ — целочисленное решение системы уравнений $\begin{cases}4y+x=-14,\\ 4y^{2}-4xy+x^{2}=16.\end{cases}$ Найдите сумму $x+y$.`,
answer: '-5',
sol: R`Второе уравнение: $(x-2y)^{2}=16$, $x-2y=\pm4$. С $x=-14-4y$ целое решение даёт $y=-3$, $x=-2$. Тогда $x+y=-5$.` },
{ idx: 23, type: 'open', topic: 'equations', subtopic: 'eq-exponential', diff: 4,
text: R`Найдите наибольшее целое решение неравенства $2^{3x-32}\cdot11^{x-6}>22^{2x-19}$.`,
answer: '12',
sol: R`$22^{2x-19}=2^{2x-19}\cdot11^{2x-19}$, поэтому неравенство равносильно $\left(\tfrac{2}{11}\right)^{x-13}>1$, то есть $x-13<0$, $x<13$. Наибольшее целое — $12$.` },
{ idx: 24, type: 'open', topic: 'trigonometry', subtopic: 'trig-equations', diff: 4,
text: R`Найдите количество корней уравнения $32\sin2x+8\cos4x=23$ на промежутке $\left[-\pi;\dfrac{3\pi}{4}\right]$.`,
answer: '4',
sol: R`Через $\cos4x=1-2\sin^{2}2x$ получаем $16\sin^{2}2x-32\sin2x+15=0$, откуда $\sin2x=0{,}75$. На указанном промежутке ($2x\in[-2\pi;\tfrac{3\pi}{2}]$) уравнение имеет $4$ корня.` },
{ idx: 25, type: 'open', topic: 'word-sequences', subtopic: 'seq-progressions', diff: 4,
text: R`Геометрическая прогрессия со знаменателем $5$ содержит $10$ членов. Сумма всех членов прогрессии равна $24$. Найдите сумму всех членов прогрессии с чётными номерами.`,
answer: '20',
sol: R`Каждый чётный член в $5$ раз больше предыдущего нечётного, поэтому сумма чётных в $5$ раз больше суммы нечётных. Если сумма нечётных равна $s$, то $s+5s=24$, $s=4$, и сумма членов с чётными номерами равна $5s=20$.` },
{ idx: 26, type: 'open', topic: 'equations', subtopic: 'eq-modulus', diff: 5,
text: R`Найдите сумму корней уравнения $\big|(x-1)(x-6)\big|\cdot\big(|x+2|+|x-8|+|x-3|\big)=11(x-1)(6-x)$.`,
answer: '13',
sol: R`Правая часть неотрицательна лишь при $1\le x\le6$; на этом отрезке $|(x-1)(x-6)|=(x-1)(6-x)$. Уравнение даёт $(x-1)(6-x)\big(S-11\big)=0$, где $S=|x+2|+|x-8|+|x-3|=10+|x-3|$. Корни: $x=1,\ 6$ (множитель $0$) и $|x-3|=1$, то есть $x=2,\ 4$. Сумма $1+2+4+6=13$.` },
{ idx: 27, type: 'open', topic: 'word-sequences', subtopic: 'word-problems', diff: 4,
text: R`Из города $A$ в город $B$, расстояние между которыми $100$ км, одновременно выезжают два автомобиля. Скорость первого автомобиля на $10$ км/ч больше скорости второго, но в пути он делает остановку на $50$ мин. Найдите наибольшее значение скорости (в км/ч) первого автомобиля, при движении с которой он прибудет в $B$ не позже второго.`,
answer: '40',
sol: R`Пусть скорость второго $v$. Условие $\dfrac{100}{v+10}+\dfrac56\le\dfrac{100}{v}$ приводит к $\dfrac56\le\dfrac{1000}{v(v+10)}$, то есть $v(v+10)\le1200$, $v\le30$. Наибольшая скорость первого $=30+10=40$.` },
{ idx: 28, type: 'open', topic: 'planimetry', subtopic: 'plan-circles', diff: 5,
text: R`Из точки $A$ проведены к окружности радиуса $\dfrac43$ касательная $AB$ ($B$ — точка касания) и секущая $AC$, проходящая через центр окружности и пересекающая её в точках $D$ и $C$. Найдите площадь $S$ треугольника $ABC$, если длина секущей $AC$ в $3$ раза больше длины касательной. В ответ запишите $5S$.`,
answer: '6',
sol: R`$AB^{2}=AO^{2}-r^{2}$ и $AC=AO+r=3\,AB$ дают $AB=\tfrac{3r}{4}=1$, $AO=\tfrac53$, $AC=3$. В координатах $B=(0{,}6;0{,}8)$, высота из $B$ к $AC$ равна $0{,}8$, площадь $=\tfrac12\cdot3\cdot0{,}8=1{,}2$. Тогда $5S=6$.` },
{ idx: 29, type: 'open', topic: 'trigonometry', subtopic: 'trig-identities', diff: 4,
text: R`Если $\cos(\alpha+14^\circ)=\dfrac35$ и $0<\alpha+14^\circ<90^\circ$, то значение выражения $15\sqrt2\,\cos(\alpha+59^\circ)$ равно … .`,
answer: '-3',
sol: R`$\cos(\alpha+59^\circ)=\cos\big((\alpha+14^\circ)+45^\circ\big)=\tfrac{\sqrt2}{2}\big(\tfrac35-\tfrac45\big)=-\tfrac{\sqrt2}{10}$ (здесь $\sin(\alpha+14^\circ)=\tfrac45$). Тогда $15\sqrt2\cdot\left(-\tfrac{\sqrt2}{10}\right)=-3$.` },
{ idx: 30, type: 'open', topic: 'equations', subtopic: 'eq-rational', diff: 5,
text: R`Решите уравнение $\dfrac{30x^{2}}{x^{4}+25}=x^{2}+2\sqrt5\,x+8$. В ответ запишите значение выражения $x\cdot|x|$, где $x$ — корень уравнения.`,
answer: '-5',
sol: R`Левая часть $\le3$ (так как $x^{4}+25\ge10x^{2}$), правая часть $=(x+\sqrt5)^{2}+3\ge3$. Равенство возможно лишь при $x=-\sqrt5$. Тогда $x\cdot|x|=-\sqrt5\cdot\sqrt5=-5$.` },
];
/* ── Сборка solution_html ────────────────────────────────────────────────── */
function ansShowOf(t) {
if (t.ansShow != null) return t.ansShow;
if (t.type === 'mc') return `${t.answer})`;
return `$${t.answer}$`;
}
function buildSolution(t) {
const ans = ansShowOf(t);
let html = `${t.sol}<div class="sol-ans">Ответ: ${ans}</div>`;
if (t.ref) html += `<div class="sol-ref" style="margin-top:6px;font-size:.85em;opacity:.7">Учебник: ${t.ref}</div>`;
return html;
}
/* ── Самопроверка (повтор логики checkAnswerServer из exam-prep.js) ────────── */
const EPS = 1e-6;
function srvToNumber(s) {
if (s == null) return NaN;
let t = String(s).trim().replace(/\$/g, '').replace(/\s+/g, '').replace(',', '.');
const f = t.match(/^(-?\d+(?:\.\d+)?)\s*\/\s*(-?\d+(?:\.\d+)?)$/);
if (f) { const n = Number(f[1]), d = Number(f[2]); return d === 0 ? NaN : n / d; }
const n = Number(t); return Number.isFinite(n) ? n : NaN;
}
function checkAnswerServer(userInput, canonical) {
if (userInput == null || canonical == null) return false;
const c = String(canonical).trim();
if (/^[а-д]$/.test(c)) return String(userInput).trim().toLowerCase() === c.toLowerCase();
if (/^[^;]+;[^;]+$/.test(c)) return false;
const cn = srvToNumber(c), un = srvToNumber(userInput);
if (Number.isNaN(cn) || Number.isNaN(un)) return false;
return Math.abs(cn - un) < EPS;
}
/* ── Валидация набора ──────────────────────────────────────────────────────── */
const problems = [];
if (TASKS.length !== N_TASKS) problems.push(`Ожидалось ${N_TASKS} заданий, получено ${TASKS.length}`);
const seen = new Set();
for (const t of TASKS) {
if (seen.has(t.idx)) problems.push(`Дубль task_idx=${t.idx}`); seen.add(t.idx);
if (t.idx < 1 || t.idx > N_TASKS) problems.push(`task_idx вне 1..${N_TASKS}: ${t.idx}`);
if (!['mc', 'open', 'long'].includes(t.type)) problems.push(`#${t.idx}: тип ${t.type}`);
if (t.type === 'mc') {
if (!Array.isArray(t.opts) || t.opts.length !== 5) problems.push(`#${t.idx}: mc должен иметь 5 вариантов`);
if (!t.opts.some(o => o[0] === t.answer)) problems.push(`#${t.idx}: answer "${t.answer}" не среди меток`);
}
if (!t.text || !t.sol) problems.push(`#${t.idx}: пустой text/sol`);
if (t.type !== 'long' && !checkAnswerServer(t.answer, t.answer))
problems.push(`#${t.idx}: answer "${t.answer}" не проходит self-check (Unicode-минус? пробел?)`);
if (//.test(String(t.answer))) problems.push(`#${t.idx}: Unicode-минус в answer`);
}
/* ── Экспорт для тестов/тиража (без запуска main при require) ──────────────── */
module.exports = { TASKS, buildSolution, ansShowOf, checkAnswerServer, EXAM, VARIANT, PROV };
if (require.main !== module) return;
/* ── Открытие БД ───────────────────────────────────────────────────────────── */
const DB = path.join(__dirname, '..', 'data', 'learnspace.db');
const db = new DatabaseSync(DB);
const track = db.prepare(`SELECT exam_key, variants_count FROM exam_tracks WHERE exam_key=?`).get(EXAM);
if (!track) { console.error(`✗ Трек '${EXAM}' не найден в exam_tracks. Прерывание.`); process.exit(1); }
/* ── DRY-RUN сводка ────────────────────────────────────────────────────────── */
console.log(`\n=== seed_ctmath_ct2013_v1 (${PROV}) variant=${VARIANT} ===`);
console.log(`Режим: ${APPLY ? 'APPLY (запись)' : 'DRY-RUN (только проверка)'}\n`);
const byType = TASKS.reduce((a, t) => (a[t.type] = (a[t.type] || 0) + 1, a), {});
console.log('Типы:', JSON.stringify(byType), '\n');
console.log('idx | type | subtopic | d | answer');
console.log('----+------+-----------------------+---+----------');
for (const t of TASKS) {
console.log(`${String(t.idx).padStart(3)} | ${t.type.padEnd(4)} | ${String(t.subtopic).padEnd(21)} | ${t.diff} | ${String(t.answer)}`);
}
if (problems.length) {
console.error(`\n✗ ПРОБЛЕМЫ (${problems.length}):`);
problems.forEach(p => console.error(' - ' + p));
console.error('\nЗапись отменена из-за ошибок валидации.');
db.close();
process.exit(1);
}
console.log(`\n✓ Валидация и self-check ответов пройдены (${N_TASKS}/${N_TASKS}).`);
/* ── APPLY: upsert ─────────────────────────────────────────────────────────── */
if (!APPLY) {
console.log('\nDRY-RUN: ничего не записано. Для записи: node backend/scripts/seed_ctmath_ct2013_v1.js --apply\n');
db.close();
process.exit(0);
}
const upsert = db.prepare(`
INSERT INTO exam_tasks
(exam_key, variant, task_idx, task_type, text_html, figure_html,
opts_json, answer, solution_html, topic, subtopic, difficulty)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(exam_key, variant, task_idx) DO UPDATE SET
task_type = excluded.task_type,
text_html = excluded.text_html,
figure_html = excluded.figure_html,
opts_json = excluded.opts_json,
answer = excluded.answer,
solution_html = excluded.solution_html,
topic = excluded.topic,
subtopic = excluded.subtopic,
difficulty = excluded.difficulty
`);
let n = 0;
db.exec('BEGIN');
try {
for (const t of TASKS) {
upsert.run(
EXAM, VARIANT, t.idx, t.type,
t.text,
t.fig || null,
t.type === 'mc' ? JSON.stringify(t.opts) : null,
t.answer,
buildSolution(t),
t.topic, t.subtopic, t.diff
);
n++;
}
const distinct = db.prepare(`SELECT COUNT(DISTINCT variant) c FROM exam_tasks WHERE exam_key=? AND variant BETWEEN 101 AND 1999`).get(EXAM).c;
db.prepare(`UPDATE exam_tracks SET variants_count=? WHERE exam_key=?`).run(distinct, EXAM);
db.exec('COMMIT');
console.log(`\n✓ Записано/обновлено ${n} заданий (variant=${VARIANT}).`);
console.log(`✓ exam_tracks.variants_count = ${distinct} (различных вариантов).`);
console.log(`\nПробник доступен: /exam-prep/ctmath → «Варианты» → «ЦТ-2013».\n`);
} catch (e) {
db.exec('ROLLBACK');
console.error('\n✗ Ошибка записи, откат транзакции:', e.message);
process.exitCode = 1;
}
db.close();