lisudoku_solver/solver/logical_solver/
common_peer_elimination_kropki.rs1use crate::solver::Solver;
2use crate::types::{SolutionStep, Rule, KropkiDotType, Area};
3use super::common_peer_elimination::CommonPeerElimination;
4use super::kropki_chain_candidates::KropkiChainCandidates;
5use super::technique::Technique;
6
7pub struct CommonPeerEliminationKropki;
9
10impl Technique for CommonPeerEliminationKropki {
11 fn get_rule(&self) -> Rule { Rule::CommonPeerEliminationKropki }
12
13 fn run(&self, solver: &Solver) -> Vec<SolutionStep> {
14 if !solver.candidates_active {
15 return vec![]
16 }
17 if solver.constraints.kropki_dots.is_empty() {
18 return vec![]
19 }
20
21 let mut steps: Vec<SolutionStep> = vec![];
22
23 for area in &solver.get_all_areas(false, false, false) {
24 let dot_types = vec![ KropkiDotType::Consecutive, KropkiDotType::Double ];
25 for dot_type in dot_types {
26 let kropki_ccs = KropkiChainCandidates::compute_area_kropki_ccs(solver, area, dot_type, false);
27 for (cells, kropki_dot_indices) in kropki_ccs {
28 let combinations: Vec<Vec<u32>> = KropkiChainCandidates::find_kropki_ccs_combinations(solver, &cells);
29
30 let cell_eliminations = CommonPeerElimination::find_cell_eliminations(cells, combinations, solver);
31
32 if cell_eliminations.is_empty() {
33 continue
34 }
35
36 steps.push(
38 SolutionStep {
39 rule: self.get_rule(),
40 cells: vec![],
41 values: cell_eliminations.iter().map(|(_, c)| c).copied().collect(), areas: kropki_dot_indices.into_iter().map(|index| Area::KropkiDot(index)).collect::<Vec<Area>>(),
43 affected_cells: cell_eliminations.iter().map(|(cell, _)| cell).copied().collect(),
44 candidates: None,
45 }
46 );
47 }
48 }
49 }
50
51 steps
52 }
53}