lisudoku_solver/solver/logical_solver/
sum_candidates.rs1use crate::solver::Solver;
2use crate::types::CellPosition;
3use super::combinations::cell_combination_logic::CellCombinationLogic;
4use super::combinations::cell_combinations_runner::{CellCombinationsRunner, State};
5
6impl Solver {
7 pub fn detect_invalid_sum_candidates(&self, cells: &Vec<CellPosition>, sum: u32) -> Vec<(CellPosition, Vec<u32>)> {
8 let mut combinations_runner = CellCombinationsRunner::new(
9 &self, Box::new(SumCombinationsLogic::new(cells, sum))
10 );
11 let (valid_candidates, _) = combinations_runner.run();
12 self.cell_candidates_diff(cells, valid_candidates)
13 }
14}
15
16struct SumCombinationsLogic<'a> {
17 sum_left: u32,
18 cells: &'a Vec<CellPosition>,
19}
20
21impl SumCombinationsLogic<'_> {
22 pub fn new<'a>(cells: &'_ Vec<CellPosition>, sum: u32) -> SumCombinationsLogic {
23 SumCombinationsLogic {
24 cells,
25 sum_left: sum,
26 }
27 }
28}
29
30impl CellCombinationLogic for SumCombinationsLogic<'_> {
31 fn cells(&self) -> Vec<CellPosition> {
32 self.cells.to_owned()
33 }
34
35 fn is_value_valid_candidate_in_cell(&self, runner: &CellCombinationsRunner, value: u32, index: usize) -> bool {
36 let cells_left_count: u32 = runner.cells.len() as u32 - index as u32 - 1;
39 let max_sum_left = cells_left_count * (19 - cells_left_count) / 2;
40
41 if value > self.sum_left {
42 return false
43 }
44 if self.sum_left - value > max_sum_left {
45 return false
46 }
47
48 true
49 }
50
51 fn should_check_all_cells_in_set(&self) -> bool { true }
52
53 fn advance_state(&mut self, _state: &mut State, value: u32, _index: usize) {
54 self.sum_left -= value;
55 }
56
57 fn restore_state(&mut self, _state: &mut State, value: u32, _index: usize) {
58 self.sum_left += value;
59 }
60}