feat(backend): leitner algorithm with tests
This commit is contained in:
49
packages/backend/src/services/leitner.ts
Normal file
49
packages/backend/src/services/leitner.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import type { AttemptResult } from '@flashcard/shared';
|
||||
|
||||
export const MAX_BOX = 5;
|
||||
// index 1..5; index 0 unused
|
||||
export const BOX_INTERVALS_SEC: Record<number, number> = {
|
||||
1: 0,
|
||||
2: 1 * 24 * 60 * 60,
|
||||
3: 3 * 24 * 60 * 60,
|
||||
4: 7 * 24 * 60 * 60,
|
||||
5: 14 * 24 * 60 * 60,
|
||||
};
|
||||
|
||||
export interface ProgressLike {
|
||||
box: number;
|
||||
correctCount: number;
|
||||
incorrectCount: number;
|
||||
}
|
||||
|
||||
export interface ProgressDelta {
|
||||
box: number;
|
||||
correctCount: number;
|
||||
incorrectCount: number;
|
||||
nextDueAt: number;
|
||||
lastShownAt: number;
|
||||
}
|
||||
|
||||
export function applyResult(
|
||||
current: ProgressLike,
|
||||
result: AttemptResult,
|
||||
nowSec: number
|
||||
): ProgressDelta {
|
||||
let box = current.box;
|
||||
let correctCount = current.correctCount;
|
||||
let incorrectCount = current.incorrectCount;
|
||||
if (result === 'correct') {
|
||||
box = Math.min(MAX_BOX, current.box + 1);
|
||||
correctCount += 1;
|
||||
} else {
|
||||
box = 1;
|
||||
incorrectCount += 1;
|
||||
}
|
||||
return {
|
||||
box,
|
||||
correctCount,
|
||||
incorrectCount,
|
||||
nextDueAt: nowSec + BOX_INTERVALS_SEC[box]!,
|
||||
lastShownAt: nowSec,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user