mod.rs (2785B)
1 mod parallel; 2 mod serial; 3 4 pub use parallel::{AsyncTester, ParallelProblemSolver}; 5 pub use serial::{SerialProblemSolver, SyncTester}; 6 7 pub struct ProblemSolver { 8 width: usize, 9 depth: usize, 10 11 cache: Vec<Vec<Option<bool>>>, 12 13 solution: Vec<usize>, 14 idx: usize, 15 16 dirty: bool, 17 } 18 19 impl ProblemSolver { 20 pub fn new(width: usize, depth: usize) -> Self { 21 Self { 22 width, 23 depth, 24 cache: vec![vec![None; depth]; width], 25 26 solution: vec![0; width], 27 idx: 0, 28 29 dirty: false, 30 } 31 } 32 } 33 34 impl ProblemSolver { 35 pub fn bail(&mut self) -> bool { 36 if self.try_advance_source() { 37 true 38 } else { 39 self.try_backtrack() 40 } 41 } 42 43 pub fn has_missing_cell(&self) -> Option<usize> { 44 self.cache 45 .iter() 46 .position(|row| row.iter().all(|c| *c == Some(false))) 47 } 48 49 fn is_cell_missing(&self, res_idx: usize, source_idx: usize) -> bool { 50 if let Some(false) = self.cache[res_idx][source_idx] { 51 return true; 52 } 53 false 54 } 55 56 fn is_current_cell_missing(&self) -> bool { 57 let res_idx = self.idx; 58 let source_idx = self.solution[res_idx]; 59 let cell = &self.cache[res_idx][source_idx]; 60 if let Some(false) = cell { 61 return true; 62 } 63 false 64 } 65 66 pub fn try_advance_resource(&mut self) -> bool { 67 if self.idx >= self.width - 1 { 68 false 69 } else { 70 self.idx += 1; 71 while self.is_current_cell_missing() { 72 if !self.try_advance_source() { 73 return false; 74 } 75 } 76 true 77 } 78 } 79 80 pub fn try_advance_source(&mut self) -> bool { 81 while self.solution[self.idx] < self.depth - 1 { 82 self.solution[self.idx] += 1; 83 if !self.is_current_cell_missing() { 84 return true; 85 } 86 } 87 false 88 } 89 90 pub fn try_backtrack(&mut self) -> bool { 91 while self.solution[self.idx] == self.depth - 1 { 92 if self.idx == 0 { 93 return false; 94 } 95 self.idx -= 1; 96 } 97 self.solution[self.idx] += 1; 98 self.prune() 99 } 100 101 pub fn prune(&mut self) -> bool { 102 for i in self.idx + 1..self.width { 103 let mut source_idx = 0; 104 while self.is_cell_missing(i, source_idx) { 105 if source_idx >= self.depth - 1 { 106 return false; 107 } 108 source_idx += 1; 109 } 110 self.solution[i] = source_idx; 111 } 112 true 113 } 114 115 pub fn is_complete(&self) -> bool { 116 self.idx == self.width - 1 117 } 118 }