-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmod.rs
140 lines (121 loc) · 3.54 KB
/
mod.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
pub mod construction;
pub mod debug;
#[derive(Clone)]
pub struct Board {
cells: [[u8; 9]; 9],
valid_ranks: [usize; 9],
valid_files: [usize; 9],
valid_boxes: [[usize; 3]; 3],
times_set: usize,
}
impl Default for Board {
fn default() -> Self {
let cells = [[0; 9]; 9];
let mut valid_ranks = [0; 9];
let mut valid_files = [0; 9];
for i in 0..9 {
for v in 1..=9 {
valid_ranks[i] |= 1 << v;
valid_files[i] |= 1 << v;
}
}
let mut valid_boxes = [[0; 3]; 3];
for x in 0..3 {
for y in 0..3 {
for v in 1..=9 {
valid_boxes[x][y] |= 1 << v;
}
}
}
Self {
cells,
valid_ranks,
valid_files,
valid_boxes,
times_set: 0,
}
}
}
impl Board {
pub fn times_set(&self) -> usize {
self.times_set
}
pub fn get(&self, x: usize, y: usize) -> u8 {
debug_assert!(x < 9);
debug_assert!(y < 9);
self.cells[x][y]
}
pub fn get_i(&self, i: usize) -> u8 {
debug_assert!(i < 81);
let x = i % 9;
let y = (i - x) / 9;
self.get(x, y)
}
pub fn set_unchecked(&mut self, x: usize, y: usize, val: u8) {
debug_assert!(x < 9);
debug_assert!(y < 9);
debug_assert_ne!(val, 0);
self.cells[x][y] = val;
debug_assert!(self.valid_ranks[y] & (1 << val) != 0);
debug_assert!(self.valid_files[x] & (1 << val) != 0);
debug_assert!(self.get_box(x, y) & (1 << val) != 0);
self.valid_ranks[y] &= !(1 << val);
self.valid_files[x] &= !(1 << val);
*self.get_box_mut(x, y) &= !(1 << val);
self.times_set += 1;
}
pub fn set_unchecked_i(&mut self, i: usize, val: u8) {
debug_assert!(i < 81);
debug_assert_ne!(val, 0);
let x = i % 9;
let y = (i - x) / 9;
self.set_unchecked(x, y, val)
}
pub fn clear(&mut self, x: usize, y: usize) {
debug_assert!(x < 9);
debug_assert!(y < 9);
let p_val = self.cells[x][y];
debug_assert!(self.valid_ranks[y] & (1 << p_val) == 0);
debug_assert!(self.valid_files[x] & (1 << p_val) == 0);
debug_assert!(self.get_box(x, y) & (1 << p_val) == 0);
self.valid_ranks[y] |= 1 << p_val;
self.valid_files[x] |= 1 << p_val;
*self.get_box_mut(x, y) |= 1 << p_val;
self.cells[x][y] = 0;
}
pub fn clear_i(&mut self, i: usize) {
debug_assert!(i < 81);
let x = i % 9;
let y = (i - x) / 9;
self.clear(x, y)
}
pub fn count(&self) -> usize {
(0..81).filter(|i| self.get_i(*i) != 0).count()
}
pub fn is_filled(&self) -> bool {
self.count() == 81
}
pub fn candidates(&self, x: usize, y: usize) -> usize {
self.valid_ranks[y] & self.valid_files[x] & self.get_box(x, y)
}
pub fn candidates_i(&self, i: usize) -> usize {
debug_assert!(i < 81);
let x = i % 9;
let y = (i - x) / 9;
self.candidates(x, y)
}
fn get_box(&self, x: usize, y: usize) -> &usize {
debug_assert!(x < 9);
debug_assert!(y < 9);
let x = x / 3;
let y = y / 3;
&self.valid_boxes[x][y]
}
fn get_box_mut(&mut self, x: usize, y: usize) -> &mut usize {
debug_assert!(x < 9);
debug_assert!(y < 9);
let x = x / 3;
let y = y / 3;
&mut self.valid_boxes[x][y]
}
}