diff options
| author | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2025-07-18 18:21:00 -0400 |
|---|---|---|
| committer | Jakob L. Kreuze <zerodaysfordays@sdf.org> | 2025-07-18 18:21:00 -0400 |
| commit | b9909fc19efb4874a2fb43d8603809a18995a781 (patch) | |
| tree | db2ab8ec99e44c3ec8de82652fa57a238a89867f /script.js.bak | |
Initial commit
Diffstat (limited to 'script.js.bak')
| -rw-r--r-- | script.js.bak | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/script.js.bak b/script.js.bak new file mode 100644 index 0000000..c81f2e5 --- /dev/null +++ b/script.js.bak @@ -0,0 +1,200 @@ +// Define a list of objects with "front" and "back" HTML content +const pages = [ + { front: "This is the front page!", back: "This is the back page!" }, + { front: "Another front page", back: "Another back page" } +]; + +// Select the first page from the list +let currentPage = pages[0]; +let showFront = true; + +// Replace the page with the front HTML initially +document.body.innerHTML = currentPage.front; + +// Add an event listener for the spacebar press +window.addEventListener('keydown', (event) => { + if (event.code === 'Space') { + // Toggle between front and back content + if (showFront) { + document.body.innerHTML = currentPage.back; + } else { + document.body.innerHTML = currentPage.front; + } + showFront = !showFront; + } +}); + +// Constants: W as an array of f64 values +const W = [ + 0.40255, 1.18385, 3.173, 15.69105, 7.1949, 0.5345, 1.4604, 0.0046, 1.54575, 0.1192, + 1.01925, 1.9395, 0.11, 0.29605, 2.2698, 0.2315, 2.9898, 0.51655, 0.6621 +]; + +// Grade enum representation +const Grade = { + Forgot: 1.0, + Hard: 2.0, + Good: 3.0, + Easy: 4.0 +}; + +// Helper to convert Grade to f64 (as in From<Grade> for f64) +function gradeToNumber(g) { + return Grade[g]; +} + +// Constants +const F = 19.0 / 81.0; +const C = -0.5; + +// retrievability(t: T, s: S) -> R +function retrievability(t, s) { + return Math.pow(1.0 + F * (t / s), C); +} + +// interval(r_d: R, s: S) -> T +function interval(rD, s) { + return (s / F) * (Math.pow(rD, 1.0 / C) - 1.0); +} + +// s_0(g: Grade) -> S +function s0(g) { + switch (g) { + case Grade.Forgot: return W[0]; + case Grade.Hard: return W[1]; + case Grade.Good: return W[2]; + case Grade.Easy: return W[3]; + default: throw new Error("Invalid grade"); + } +} + +// s_success(d: D, s: S, r: R, g: Grade) -> S +function sSuccess(d, s, r, g) { + const tD = 11.0 - d; + const tS = Math.pow(s, -W[9]); + const tR = Math.exp(W[10] * (1.0 - r)) - 1.0; + const h = (g === Grade.Hard) ? W[15] : 1.0; + const b = (g === Grade.Easy) ? W[16] : 1.0; + const c = Math.exp(W[8]); + const alpha = 1.0 + tD * tS * tR * h * b * c; + return s * alpha; +} + +// s_fail(d: D, s: S, r: R) => number +function sFail(d, s, r) { + return Math.exp(W[8]) - 1.0; +} + +// Main function +function main() { + // All functions +} + +const W = [ + 0.40255, 1.18385, 3.173, 15.69105, 7.1949, 0.5345, 1.4604, 0.0046, 1.54575, 0.1192, 1.01925, + 1.9395, 0.11, 0.29605, 2.2698, 0.2315, 2.9898, 0.51655, 0.6621, +]; + +const F = 19.0 / 81.0; +const C = -0.5; + +const Grade = { + Forgot: 1.0, + Hard: 2.0, + Good: 3.0, + Easy: 4.0 +}; + +function retrievability(t, s) { + return Math.pow(1.0 + F * (t / s), C); +} + +function interval(r_d, s) { + return (s / F) * (Math.pow(r_d, 1.0 / C) - 1.0); +} + +function s_0(g) { + switch (g) { + case Grade.Forgot: return W[0]; + case Grade.Hard: return W[1]; + case Grade.Good: return W[2]; + case Grade.Easy: return W[3]; + } +} + +function s_success(d, s, r, g) { + const t_d = 11.0 - d; + const t_s = Math.pow(s, -W[9]); + const t_r = Math.exp(W[10] * (1.0 - r)) - 1.0; + const h = g === Grade.Hard ? W[15] : 1.0; + const b = g === Grade.Easy ? W[16] : 1.0; + const c = Math.exp(W[8]); + const alpha = 1.0 + t_d * t_s * t_r * h * b * c; + return s * alpha; +} + +function s_fail(d, s, r) { + const d_f = Math.pow(d, -W[12]); + const s_f = Math.pow(s + 1.0, W[13]) - 1.0; + const r_f = Math.exp(W[14] * (1.0 - r)); + const c_f = W[11]; + const result = d_f * s_f * r_f * c_f; + return Math.min(result, s); +} + +function stability(d, s, r, g) { + return g === Grade.Forgot ? s_fail(d, s, r) : s_success(d, s, r, g); +} + +function clamp_d(d) { + return Math.min(10.0, Math.max(1.0, d)); +} + +function d_0(g) { + const g_value = Grade[g]; + return clamp_d(W[4] - Math.exp(W[5] * (g_value - 1.0)) + 1.0); +} + +function difficulty(d, g) { + return clamp_d(W[7] * d_0('Easy') + (1.0 - W[7]) * dp(d, g)); +} + +function dp(d, g) { + return d + delta_d(g) * ((10.0 - d) / 9.0); +} + +function delta_d(g) { + const g_value = Grade[g]; + return -W[6] * (g_value - 3.0); +} + +function sim(grades) { + let t = 0.0; + const r_d = 0.9; + const steps = []; + + // Initial review + if (grades.length === 0) { + throw new Error("Grades cannot be empty"); + } + + let gradesCopy = [...grades]; + let g = gradesCopy.shift(); // Remove the first grade + let s = s_0(g); + let d = d_0(g); + let i = Math.max(Math.round(interval(r_d, s)), 1.0); + + steps.push({ t, s, d, i }); + + // n-th review + for (let g of gradesCopy) { + t += i; + const r = retrievability(i, s); + s = stability(d, s, r, g); + d = difficulty(d, g); + i = Math.max(Math.round(interval(r_d, s)), 1.0); + steps.push({ t, s, d, i }); + } + + return steps; +} |