Skip to content

Commit e33f79c

Browse files
committed
Each strategy resides in its own file.
1 parent eb9be4a commit e33f79c

File tree

15 files changed

+1815
-1770
lines changed

15 files changed

+1815
-1770
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ opt-level = 2
4848

4949
[[bin]]
5050
name = "sudokui"
51-
path = "src/ui.rs"
51+
path = "src/ui/ui.rs"
5252

5353
[[bin]]
5454
name = "rate"
55-
path = "src/rate.rs"
55+
path = "src/rate/rate.rs"
5656
required-features = ["dump"]
5757

5858
[[bin]]
5959
name = "gen"
60-
path = "src/gen.rs"
60+
path = "src/gen/gen.rs"
6161
required-features = ["dump"]

src/claimingpair.rs

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
use crate::{Candidate, RemovalResult, Strategy, StrategyResult, Sudoku, Unit};
2+
3+
impl Sudoku {
4+
fn is_claiming_pair(cells_with_num: &[usize]) -> bool {
5+
cells_with_num.len() == 2 && (cells_with_num[0] / 3 == cells_with_num[1] / 3)
6+
}
7+
8+
pub fn find_claiming_pair_in_rows(&self) -> RemovalResult {
9+
let mut result = RemovalResult::empty();
10+
for row in 0..9 {
11+
for num in 1..=9 {
12+
// Track cells with candidate `num` in this row
13+
let cells_with_num: Vec<_> = (0..9)
14+
.filter(|&col| self.candidates[row][col].contains(&num))
15+
.collect();
16+
if !Self::is_claiming_pair(&cells_with_num) {
17+
continue;
18+
}
19+
let col1 = cells_with_num[0];
20+
let col2 = cells_with_num[1];
21+
let box_col = col1 / 3;
22+
let start_row = 3 * (row / 3);
23+
// Remove this candidate from other cells in the same box but different row
24+
for r in start_row..start_row + 3 {
25+
if r == row {
26+
continue; // Skip the original row
27+
}
28+
for c in (box_col * 3)..(box_col * 3 + 3) {
29+
if self.candidates[r][c].contains(&num) {
30+
result.candidates_about_to_be_removed.insert(Candidate {
31+
row: r,
32+
col: c,
33+
num,
34+
});
35+
}
36+
}
37+
}
38+
if result.will_remove_candidates() {
39+
result.candidates_affected.push(Candidate {
40+
row,
41+
col: col1,
42+
num,
43+
});
44+
result.candidates_affected.push(Candidate {
45+
row,
46+
col: col2,
47+
num,
48+
});
49+
result.unit = Some(Unit::Row);
50+
result.unit_index = Some(vec![row]);
51+
return result;
52+
}
53+
}
54+
}
55+
result
56+
}
57+
58+
pub fn find_claiming_pair_in_cols(&self) -> RemovalResult {
59+
let mut result = RemovalResult::empty();
60+
for col in 0..9 {
61+
for num in 1..=9 {
62+
let cells_with_num: Vec<_> = (0..9)
63+
.filter(|&row| self.candidates[row][col].contains(&num))
64+
.collect();
65+
if !Self::is_claiming_pair(&cells_with_num) {
66+
continue;
67+
}
68+
let row1 = cells_with_num[0];
69+
let row2 = cells_with_num[1];
70+
let box_idx = row1 / 3;
71+
let start_col = 3 * (col / 3);
72+
// Remove this candidate from other cells in the same box but different column
73+
for c in start_col..start_col + 3 {
74+
if c == col {
75+
continue; // Skip the original column
76+
}
77+
for r in (box_idx * 3)..(box_idx * 3 + 3) {
78+
if self.candidates[r][c].contains(&num) {
79+
result.candidates_about_to_be_removed.insert(Candidate {
80+
row: r,
81+
col: c,
82+
num,
83+
});
84+
}
85+
}
86+
}
87+
if result.will_remove_candidates() {
88+
result.candidates_affected.push(Candidate {
89+
row: row1,
90+
col,
91+
num,
92+
});
93+
result.candidates_affected.push(Candidate {
94+
row: row2,
95+
col,
96+
num,
97+
});
98+
result.unit = Some(Unit::Column);
99+
result.unit_index = Some(vec![col]);
100+
return result;
101+
}
102+
}
103+
}
104+
result
105+
}
106+
107+
pub fn find_claiming_pair(&self) -> StrategyResult {
108+
log::info!("Finding claiming pairs in rows");
109+
let result = self.find_claiming_pair_in_rows();
110+
if result.will_remove_candidates() {
111+
return StrategyResult {
112+
strategy: Strategy::ClaimingPair,
113+
removals: result,
114+
};
115+
}
116+
log::info!("Finding claiming pairs in columns");
117+
let result = self.find_claiming_pair_in_cols();
118+
StrategyResult {
119+
strategy: Strategy::ClaimingPair,
120+
removals: result,
121+
}
122+
}
123+
}
File renamed without changes.

0 commit comments

Comments
 (0)