Fsrs pools change
This commit is contained in:
1 parent
8603e9b981
commit
936efd0e99
1 file changed
+31
-57
+31
-57
@@ -1,7 +1,6 @@
|
||||
use crate::data::entities::CardState;
|
||||
use chrono::{Local, TimeDelta};
|
||||
use fsrs::FSRS;
|
||||
use log::{debug, info};
|
||||
use rand::distr::weighted::WeightedIndex;
|
||||
use rand::prelude::ThreadRng;
|
||||
use rand::prelude::{Distribution, SliceRandom};
|
||||
@@ -67,6 +66,18 @@ pub struct SemiRandomSRSModule {
|
||||
generator: ThreadRng,
|
||||
}
|
||||
impl SRSModule for SemiRandomSRSModule {
|
||||
fn new(set: &[&CardState]) -> Self {
|
||||
let weights = set
|
||||
.iter()
|
||||
.map(|s| (100.0 / s.calculated_score()).powf(2.0) * 2.0)
|
||||
.collect::<Vec<f32>>();
|
||||
|
||||
Self {
|
||||
generator: rng(),
|
||||
last_weights: WeightedIndex::new(weights).expect("Incorrect weights update"),
|
||||
history: vec![],
|
||||
}
|
||||
}
|
||||
fn next(&mut self, set: &[&CardState]) -> usize {
|
||||
let index = self.last_weights.sample(&mut self.generator);
|
||||
|
||||
@@ -87,18 +98,6 @@ impl SRSModule for SemiRandomSRSModule {
|
||||
.update_weights(&[(index, &new_weight)])
|
||||
.expect("update weights error");
|
||||
}
|
||||
fn new(set: &[&CardState]) -> Self {
|
||||
let weights = set
|
||||
.iter()
|
||||
.map(|s| (100.0 / s.calculated_score()).powf(2.0) * 2.0)
|
||||
.collect::<Vec<f32>>();
|
||||
|
||||
Self {
|
||||
generator: rng(),
|
||||
last_weights: WeightedIndex::new(weights).expect("Incorrect weights update"),
|
||||
history: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
impl SemiRandomSRSModule {
|
||||
fn history_len(&self, set: &[&CardState]) -> usize {
|
||||
@@ -114,6 +113,16 @@ pub struct WorstWordsSRSModule {
|
||||
rounds_count: u8,
|
||||
}
|
||||
impl SRSModule for WorstWordsSRSModule {
|
||||
fn new(_: &[&CardState]) -> Self {
|
||||
WorstWordsSRSModule {
|
||||
pool_size: PARTIAL_POOL_SIZE,
|
||||
rounds_count: 2,
|
||||
rounds_remaining: 0,
|
||||
pool: vec![],
|
||||
queue: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self, set: &[&CardState]) -> usize {
|
||||
if self.rounds_remaining == 0 {
|
||||
self.fill_pool(set);
|
||||
@@ -131,16 +140,6 @@ impl SRSModule for WorstWordsSRSModule {
|
||||
}
|
||||
|
||||
fn open(&mut self, _: WordOpenMode, _: usize, _: &mut CardState) {}
|
||||
|
||||
fn new(_: &[&CardState]) -> Self {
|
||||
WorstWordsSRSModule {
|
||||
pool_size: PARTIAL_POOL_SIZE,
|
||||
rounds_count: 2,
|
||||
rounds_remaining: 0,
|
||||
pool: vec![],
|
||||
queue: vec![],
|
||||
}
|
||||
}
|
||||
}
|
||||
impl WorstWordsSRSModule {
|
||||
fn fill_pool(&mut self, set: &[&CardState]) {
|
||||
@@ -157,9 +156,7 @@ impl WorstWordsSRSModule {
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct FsrsModule {
|
||||
today_set: Vec<usize>,
|
||||
solved: Vec<usize>,
|
||||
current_group: Vec<usize>,
|
||||
next_round: Vec<usize>,
|
||||
queue: Vec<usize>,
|
||||
rng: ThreadRng,
|
||||
fsrs: FSRS,
|
||||
@@ -170,29 +167,22 @@ impl SRSModule for FsrsModule {
|
||||
let today = Local::now().date_naive();
|
||||
|
||||
let mut new = Self {
|
||||
today_set: set
|
||||
queue: set
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|(_, c)| c.fsrs_open_day <= today)
|
||||
.map(|(index, _)| index)
|
||||
.collect(),
|
||||
current_group: vec![],
|
||||
queue: vec![],
|
||||
solved: vec![],
|
||||
next_round: vec![],
|
||||
rng: rng(),
|
||||
fsrs: FSRS::default(),
|
||||
};
|
||||
new.today_set.shuffle(&mut new.rng);
|
||||
new.fill_partial_pool();
|
||||
new.queue.shuffle(&mut new.rng);
|
||||
|
||||
new
|
||||
}
|
||||
|
||||
fn next(&mut self, _: &[&CardState]) -> usize {
|
||||
if self.current_group.is_empty() {
|
||||
self.fill_partial_pool();
|
||||
}
|
||||
|
||||
if self.queue.is_empty() {
|
||||
self.fill_queue();
|
||||
self.queue.shuffle(&mut self.rng);
|
||||
@@ -230,37 +220,21 @@ impl SRSModule for FsrsModule {
|
||||
updated_word.fsrs_open_day = next_day;
|
||||
updated_word.fsrs_opened = updated_word.last_open.date_naive();
|
||||
|
||||
if (updated_word.fsrs_open_day != today && !first_time)
|
||||
|| (first_time && status == WordOpenMode::Easy)
|
||||
if (updated_word.fsrs_open_day == today && !first_time)
|
||||
|| (first_time && status != WordOpenMode::Easy)
|
||||
{
|
||||
info!("For today word on index {} solved", index);
|
||||
self.solved.push(index);
|
||||
let index = self.current_group.iter().position(|x| *x == index).unwrap();
|
||||
self.current_group.remove(index);
|
||||
self.next_round.push(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FsrsModule {
|
||||
fn fill_partial_pool(&mut self) {
|
||||
debug!("Filling partial pool");
|
||||
self.current_group.extend(
|
||||
self.today_set
|
||||
.iter()
|
||||
.filter(|x| !self.solved.contains(*x))
|
||||
.take(PARTIAL_POOL_SIZE),
|
||||
);
|
||||
|
||||
self.queue.clear();
|
||||
self.queue.extend(self.current_group.clone());
|
||||
}
|
||||
|
||||
fn fill_queue(&mut self) {
|
||||
self.queue.extend(self.current_group.clone());
|
||||
self.queue.append(&mut self.next_round);
|
||||
}
|
||||
|
||||
pub fn finished(&self) -> bool {
|
||||
self.today_set.len() == self.solved.len()
|
||||
self.queue.is_empty() && self.next_round.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user