lisudoku_solver/solver/logical_solver/
arrow_advanced_candidates.rs1use crate::solver::Solver;
2use crate::solver::logical_solver::combinations::cell_combinations_runner::CellCombinationsRunner;
3use crate::types::{SolutionStep, Rule, Area};
4use super::technique::Technique;
5
6pub struct ArrowAdvancedCandidates;
8
9impl Technique for ArrowAdvancedCandidates {
10 fn is_candidate_validity_update_step(&self) -> bool { true }
11 fn get_rule(&self) -> Rule { Rule::ArrowAdvancedCandidates }
12
13 fn run(&self, solver: &Solver) -> Vec<SolutionStep> {
14 if !solver.candidates_active {
15 return vec![]
16 }
17
18 solver.constraints.arrows.iter().enumerate().flat_map(|(arrow_index, arrow)| {
19 let cells = arrow.all_cells();
20
21 if solver.count_empty_cells_in_list(&cells) > 8 {
24 return vec![]
25 }
26
27 let mut arrow_combinatons_logic_factory = solver.arrow_combinatons_logic_factory.borrow_mut();
28 let combination_logic = arrow_combinatons_logic_factory.create(arrow, solver);
29 let mut runner = CellCombinationsRunner::new(solver, Box::new(combination_logic));
30 let (_, combinations) = runner.run();
31
32 let invalid_candidates = solver.eliminate_combinations(&combinations, &cells);
33
34 invalid_candidates.into_iter().map(|(cell, invalid_values)| {
36 self.build_simple_solution_step(
37 invalid_values,
38 vec![ Area::Arrow(arrow_index) ],
39 vec![ cell ]
40 )
41 }).collect::<Vec<_>>()
42 }).collect()
43 }
44}