ts-fsrs
FSRSのts実装
https://github.com/open-spaced-repetition/ts-fsrs
https://doc.deno.land/https://esm.sh/ts-fsrs@4.3.0
コメントに中国語が混じっている
どうやらbrowserで動かせるようだ
deno-anki作らなくてもいいかも
demo
https://github.com/ishiko732/ts-fsrs-demo
乱数生成にAlea algorithmが使われている
ReviewLogとCardの違いがよくわからない
READMEに説明があった
code:ts
interface Card {
/** Date when the card is next due for review */
due: Date;
/** A measure of how well the information is retained */
stability: number;
/** Reflects the inherent difficulty of the card content */
difficulty: number;
/** Days since the card was last reviewed */
elapsed_days: number;
/** The interval at which the card is next scheduled */
scheduled_days: number;
/** Total number of times the card has been reviewed */
reps: number;
/** Times the card was forgotten or remembered incorrectly */
lapses: number;
/** The current state of the card (New, Learning, Review, Relearning) */
state: State;
/** The most recent review date, if applicable */
last_review?: Date;
}
interface ReviewLog {
/** Rating of the review (Again, Hard, Good, Easy) */
rating: Rating;
/** State of the review (New, Learning, Review, Relearning) */
state: State;
/** Date of the last scheduling */
due: Date;
/** Stability of the card before the review */
stability: number;
/** Difficulty of the card before the review */
difficulty: number;
/** Number of days elapsed since the last review */
elapsed_days: number;
/** Number of days between the last two reviews */
last_elapsed_days: number;
/** Number of days until the next review */
scheduled_days: number;
/** Date of the review */
review: Date;
}
ReviewLogのstability,difficulty,elapsed_days,scheduled_daysは、review前のcardの状態を表す
last_elapsed_daysには前の前のcardのelapsed_daysが入る
Cardのlast_reviewとdueの差がscheduled_daysになる
ReviewLogがあれば、empty cardからReviewLog["review"]時点のCardを復元できる
それがFSRS.rollback()
code:sample.ts
// from https://github.com/open-spaced-repetition/ts-fsrs?tab=readme-ov-file#example
import {
createEmptyCard,
formatDate,
fsrs,
generatorParameters,
Rating,
State,
} from "npm:ts-fsrs";
const params = generatorParameters({
enable_fuzz: true,
enable_short_term: false,
});
const f = fsrs(params);
const card = createEmptyCard(new Date("2022-2-1 10:00:00")); // createEmptyCard();
console.group("Empty");
console.table({
[card_empty]: {
stability: card.stability,
difficulty: card.difficulty,
elapsed_days: card.elapsed_days,
scheduled_days: card.scheduled_days,
state: Statecard.state,
due: formatDate(card.due),
reps: card.reps,
lapses: card.lapses,
last_review: card.last_review ? formatDate(card.last_review) : undefined,
},
});
console.log(
"----------------------------------------------------------------",
);
console.groupEnd();
const now = new Date("2022-2-2 10:00:00"); // new Date();
const scheduling_cards = f.repeat(card, now);
// console.log(scheduling_cards);
for (const item of scheduling_cards) {
// grades = Rating.Again, Rating.Hard, Rating.Good, Rating.Easy
const grade = item.log.rating;
const { log, card } = item;
console.group(${Rating[grade]});
console.table({
[card_${Rating[grade]}]: {
stability: card.stability,
difficulty: card.difficulty,
elapsed_days: card.elapsed_days,
scheduled_days: card.scheduled_days,
state: Statecard.state,
due: formatDate(card.due),
reps: card.reps,
lapses: card.lapses,
last_review: card.last_review ? formatDate(card.last_review) : undefined,
},
});
console.table({
[log_${Rating[grade]}]: {
stability: log.stability,
difficulty: log.difficulty,
elapsed_days: log.elapsed_days,
scheduled_days: log.scheduled_days,
state: Statelog.state,
due: formatDate(log.due),
rating: Ratinglog.rating,
last_elapsed_days: log.last_elapsed_days,
review: formatDate(log.review),
},
});
console.groupEnd();
console.log(
"----------------------------------------------------------------",
);
}
#2024-10-16 09:38:42
#2024-10-02 08:12:58
#2024-09-17 22:15:58