From 3ab41e14f8080807877115d19f372574893298c7 Mon Sep 17 00:00:00 2001 From: ishiko Date: Wed, 13 Mar 2024 20:14:46 +0800 Subject: [PATCH] Fix/fuzz=false wrong calc next_ivl (#74) * Fix/enable_fuzz=false wrong calc next_ivl * 3.5.1 * Test/next_ivl --- __tests__/algorithm.test.ts | 39 +++++++++++++++++++++++++++++++++++++ package.json | 2 +- src/fsrs/algorithm.ts | 6 +++--- src/fsrs/default.ts | 2 +- 4 files changed, 44 insertions(+), 5 deletions(-) create mode 100644 __tests__/algorithm.test.ts diff --git a/__tests__/algorithm.test.ts b/__tests__/algorithm.test.ts new file mode 100644 index 0000000..dab63a7 --- /dev/null +++ b/__tests__/algorithm.test.ts @@ -0,0 +1,39 @@ +import { fsrs, FSRS, generatorParameters, get_fuzz_range } from "../src/fsrs"; + +describe("next_interval", () => { + const DECAY: number = -0.5; + const FACTOR: number = Math.pow(0.9, 1 / DECAY) - 1; + + it("next_ivl", () => { + const desired_retentions: number[] = Array.from( + { length: 10 }, + (_, i) => (i + 1) / 10, + ); + const intervals: number[] = desired_retentions.map((r) => + fsrs({ request_retention: r }).next_interval(1.0, 0, false), + ); + expect(intervals).toEqual([422, 102, 43, 22, 13, 8, 4, 2, 1, 1]); + }); + + // https://github.com/open-spaced-repetition/ts-fsrs/pull/74 + it("next_ivl[max_limit]", () => { + const params = generatorParameters({ maximum_interval: 365 }); + const intervalModifier = + (Math.pow(params.request_retention, 1 / DECAY) - 1) / FACTOR; + const f: FSRS = fsrs(params); + + const s = 737.47; + const next_ivl = f.next_interval(s, 0, false); + expect(next_ivl).toEqual(params.maximum_interval); + + const t_fuzz = 98; + const next_ivl_fuzz = f.next_interval(s, t_fuzz, true); + const { min_ivl, max_ivl } = get_fuzz_range( + s * intervalModifier, + t_fuzz, + params.maximum_interval, + ); + expect(next_ivl_fuzz).toBeGreaterThanOrEqual(min_ivl); + expect(next_ivl_fuzz).toBeLessThanOrEqual(params.maximum_interval); + }); +}); diff --git a/package.json b/package.json index 64ea540..7e8ce61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ts-fsrs", - "version": "3.5.0", + "version": "3.5.1", "description": "ts-fsrs is a ES modules package based on TypeScript, used to implement the Free Spaced Repetition Scheduler (FSRS) algorithm. It helps developers apply FSRS to their flashcard applications, there by improving the user learning experience.", "main": "dist/index.cjs", "module": "dist/index.mjs", diff --git a/src/fsrs/algorithm.ts b/src/fsrs/algorithm.ts index b9d4495..223f9c6 100644 --- a/src/fsrs/algorithm.ts +++ b/src/fsrs/algorithm.ts @@ -132,9 +132,9 @@ export class FSRSAlgorithm { elapsed_days: number, enable_fuzz: boolean = this.param.enable_fuzz, ): int { - const newInterval = Math.max( - 1, - Math.round(s * this.intervalModifier), + const newInterval = Math.min( + Math.max(1, Math.round(s * this.intervalModifier)), + this.param.maximum_interval, ) as int; return this.apply_fuzz(newInterval, elapsed_days, enable_fuzz); } diff --git a/src/fsrs/default.ts b/src/fsrs/default.ts index 5cc698e..7088aac 100644 --- a/src/fsrs/default.ts +++ b/src/fsrs/default.ts @@ -9,7 +9,7 @@ export const default_w = [ ]; export const default_enable_fuzz = false; -export const FSRSVersion: string = "3.5.0"; +export const FSRSVersion: string = "3.5.1"; export const generatorParameters = ( props?: Partial,