serial.rs (1964B)
1 use super::ProblemSolver; 2 use std::ops::{Deref, DerefMut}; 3 4 pub trait SyncTester { 5 fn test_sync(&self, res_idx: usize, source_idx: usize) -> bool; 6 } 7 8 pub struct SerialProblemSolver(ProblemSolver); 9 10 impl Deref for SerialProblemSolver { 11 type Target = ProblemSolver; 12 13 fn deref(&self) -> &Self::Target { 14 &self.0 15 } 16 } 17 18 impl DerefMut for SerialProblemSolver { 19 fn deref_mut(&mut self) -> &mut Self::Target { 20 &mut self.0 21 } 22 } 23 24 impl SerialProblemSolver { 25 pub fn new(width: usize, depth: usize) -> Self { 26 Self(ProblemSolver::new(width, depth)) 27 } 28 } 29 30 impl SerialProblemSolver { 31 fn test_current_cell<T>(&mut self, tester: &T) -> bool 32 where 33 T: SyncTester, 34 { 35 let res_idx = self.idx; 36 let source_idx = self.solution[res_idx]; 37 let cell = &mut self.cache[res_idx][source_idx]; 38 *cell.get_or_insert_with(|| tester.test_sync(res_idx, source_idx)) 39 } 40 41 pub fn try_next<T>(&mut self, tester: &T, prefetch: bool) -> Result<Option<&[usize]>, usize> 42 where 43 T: SyncTester, 44 { 45 if self.width == 0 || self.depth == 0 { 46 return Ok(None); 47 } 48 if self.dirty { 49 if !self.bail() { 50 return Ok(None); 51 } 52 self.dirty = false; 53 } 54 loop { 55 if !self.test_current_cell(tester) { 56 if !self.bail() { 57 if let Some(res_idx) = self.has_missing_cell() { 58 return Err(res_idx); 59 } else { 60 return Ok(None); 61 } 62 } 63 continue; 64 } 65 if self.is_complete() { 66 if !prefetch { 67 self.dirty = true; 68 } 69 return Ok(Some(&self.solution)); 70 } 71 if !self.try_advance_resource() { 72 return Ok(None); 73 } 74 } 75 } 76 }