45 lines
1.9 KiB
JavaScript
45 lines
1.9 KiB
JavaScript
// ── Rehearser train-mode comparison helpers ─────────────────────────────────
|
||
// Recording/state-machine wiring remains in rehearser.js; these pure helpers
|
||
// are isolated so transcript comparison can be tested and migrated first.
|
||
(function (root) {
|
||
|
||
function _trainNormWords(str) {
|
||
return (str || '').toLowerCase().replace(/[^a-zäöüàáâãèéêëìíîïòóôõùúûüýÿæœßа-яёА-ЯЁ0-9\s]/g, '').trim().split(/\s+/).filter(Boolean);
|
||
}
|
||
|
||
function _trainLcs(a, b) {
|
||
const R = a.length, C = b.length;
|
||
const dp = Array.from({length: R + 1}, () => new Int16Array(C + 1));
|
||
for (let i = 1; i <= R; i++) for (let j = 1; j <= C; j++)
|
||
dp[i][j] = a[i-1] === b[j-1] ? dp[i-1][j-1] + 1 : Math.max(dp[i-1][j], dp[i][j-1]);
|
||
let i = R, j = C; const seq = [];
|
||
while (i > 0 && j > 0) {
|
||
if (a[i-1] === b[j-1]) { seq.unshift([i-1, j-1]); i--; j--; }
|
||
else if (dp[i-1][j] >= dp[i][j-1]) i--;
|
||
else j--;
|
||
}
|
||
return seq;
|
||
}
|
||
|
||
function _trainCompare(expected, actual) {
|
||
const ew = _trainNormWords(expected), aw = _trainNormWords(actual);
|
||
if (!ew.length) return { html_exp: '', html_act: '', score: 1 };
|
||
const pairs = _trainLcs(ew, aw);
|
||
const matchedE = new Set(pairs.map(p => p[0]));
|
||
const matchedA = new Set(pairs.map(p => p[1]));
|
||
const expHtml = ew.map((w, i) => matchedE.has(i)
|
||
? `<span class="tw-ok">${escHtml(w)}</span>`
|
||
: `<span class="tw-miss">${escHtml(w)}</span>`).join(' ');
|
||
const actHtml = aw.map((w, i) => matchedA.has(i)
|
||
? `<span class="tw-ok">${escHtml(w)}</span>`
|
||
: `<span class="tw-extra">${escHtml(w)}</span>`).join(' ');
|
||
const score = ew.length ? Math.round((matchedE.size / ew.length) * 100) : 100;
|
||
return { html_exp: expHtml, html_act: actHtml, score };
|
||
}
|
||
|
||
root._trainCompare = _trainCompare;
|
||
root.TTVC = root.TTVC || {};
|
||
root.TTVC.rehearser = root.TTVC.rehearser || {};
|
||
root.TTVC.rehearser.train = { compare: _trainCompare };
|
||
})(window);
|