1use itertools::Itertools;
2#[cfg(any(feature = "py", feature = "rs"))]
3use rand::seq::SliceRandom;
4#[cfg(any(feature = "py", feature = "rs"))]
5use rand::thread_rng;
6use std::cmp::{max, min};
7use std::vec;
8#[cfg(feature = "js")]
10use getrandom::getrandom;
11
12use crate::safe_board;
13use crate::safe_board::BoardSize;
14use crate::ENUM_LIMIT;
15
16pub fn cal_op<T>(board_raw: &T) -> usize
20where
21 T: std::ops::Index<usize> + safe_board::BoardSize,
22 T::Output: std::ops::Index<usize, Output = i32>,
23{
24 let row = board_raw.get_row();
25 let column = board_raw.get_column();
26 let mut board = vec![vec![0; column]; row];
27 for i in 0..row {
28 for j in 0..column {
29 board[i][j] = board_raw[i][j];
30 }
31 }
32 let mut op = 0;
33 for i in 0..row {
34 for j in 0..column {
35 if board[i][j] == 0 {
36 infect_board(&mut board, i, j);
37 op += 1;
38 }
39 }
40 }
41 op
42}
43
44fn infect_board(board: &mut Vec<Vec<i32>>, x: usize, y: usize) {
46 let row = board.len();
47 let column = board[0].len();
48 board[x][y] = 1;
49 for i in max(1, x) - 1..min(row, x + 2) {
50 for j in max(1, y) - 1..min(column, y + 2) {
51 if board[i][j] == 0 {
52 infect_board(board, i, j);
53 }
54 }
55 }
56}
57
58pub fn cal_isl<T>(raw_board: &T) -> usize
60where
61 T: std::ops::Index<usize> + safe_board::BoardSize,
62 T::Output: std::ops::Index<usize, Output = i32>,
63{
64 let row = raw_board.get_row();
65 let column = raw_board.get_column();
66 let mut board = vec![vec![1; column]; row];
67 for i in 0..row {
68 for j in 0..column {
69 if raw_board[i][j] <= 0 {
70 continue;
71 }
72 let mut flag = true;
73 'outer: for m in max(1, i) - 1..min(row, i + 2) {
74 for n in max(1, j) - 1..min(column, j + 2) {
75 if raw_board[m][n] == 0 {
76 flag = false;
77 break 'outer;
78 }
79 }
80 }
81 if flag {
82 board[i][j] = 0;
83 }
84 }
85 }
86 cal_op(&board)
87}
88
89pub fn cal_cell_nums<T>(raw_board: &T) -> [usize; 9]
91where
92 T: std::ops::Index<usize> + BoardSize,
93 T::Output: std::ops::Index<usize, Output = i32>,
94{
95 let row = raw_board.get_row();
96 let column = raw_board.get_column();
97 let mut ans = [0; 9];
98 for i in 0..row {
99 for j in 0..column {
100 if raw_board[i][j] < 0 {
101 continue;
102 }
103 ans[raw_board[i][j] as usize] += 1;
104 }
105 }
106 ans
107}
108
109pub fn refresh_matrix(
112 game_board: &Vec<Vec<i32>>,
113) -> (Vec<Vec<i32>>, Vec<(usize, usize)>, Vec<i32>) {
114 let row = game_board.len();
115 let column = game_board[0].len();
116 let mut MatrixA: Vec<Vec<i32>> = Vec::new();
117 let mut Matrixx: Vec<(usize, usize)> = Vec::new();
118 let mut Matrixb: Vec<i32> = Vec::new();
119 let mut MatrixARowNum = 0;
120 let mut MatrixAColumnNum = 0;
121
122 for i in 0..row {
123 for j in 0..column {
124 if game_board[i][j] > 0 && game_board[i][j] < 10 {
125 let mut flag: bool = false;
126 for m in max(1, i) - 1..min(row, i + 2) {
127 for n in max(1, j) - 1..min(column, j + 2) {
128 if game_board[m][n] == 10 {
129 flag = true;
130 }
131 }
132 }
133 if flag {
134 MatrixA.push(vec![0; MatrixAColumnNum]);
135 Matrixb.push(game_board[i][j]);
136 MatrixARowNum += 1;
137 for m in max(1, i) - 1..min(row, i + 2) {
138 for n in max(1, j) - 1..min(column, j + 2) {
139 if game_board[m][n] == 11 {
140 Matrixb[MatrixARowNum - 1] -= 1
141 } else if game_board[m][n] == 10 {
142 let mut flag_exit: bool = false;
143 for idMatrixx in 0..MatrixAColumnNum {
144 if Matrixx[idMatrixx].0 == m && Matrixx[idMatrixx].1 == n {
145 flag_exit = true;
146 MatrixA[MatrixARowNum - 1][idMatrixx] = 1;
147 }
148 }
149 if !flag_exit {
150 for ii in 0..MatrixARowNum {
151 MatrixA[ii].push(0)
152 }
153 Matrixx.push((m, n));
154 MatrixAColumnNum += 1;
155 MatrixA[MatrixARowNum - 1][MatrixAColumnNum - 1] = 1;
156 }
157 }
158 }
159 }
160 }
161 }
162 }
163 }
164 (MatrixA, Matrixx, Matrixb)
165}
166
167pub fn refresh_matrixs(
170 board_of_game: &Vec<Vec<i32>>,
171) -> (
172 Vec<Vec<Vec<i32>>>,
173 Vec<Vec<(usize, usize)>>,
174 Vec<Vec<i32>>,
175 usize,
176 usize,
177) {
178 let row = board_of_game.len();
183 let column = board_of_game[0].len();
184 let mut unknow_block = 0;
185 let mut is_minenum = 0;
186 let mut matrix_as = vec![];
187 let mut matrix_xs = vec![];
188 let mut matrix_bs = vec![];
189 let mut all_cell: Vec<(usize, usize)> = vec![]; for i in 0..row {
191 for j in 0..column {
192 if board_of_game[i][j] >= 0 && board_of_game[i][j] < 10 {
193 'outer: for m in max(1, i) - 1..min(row, i + 2) {
194 for n in max(1, j) - 1..min(column, j + 2) {
195 if board_of_game[m][n] == 10 {
196 all_cell.push((i, j));
197 break 'outer;
198 }
199 }
200 }
201 } else if board_of_game[i][j] == 10 {
202 let mut flag = true;
204 for m in max(1, i) - 1..min(row, i + 2) {
205 for n in max(1, j) - 1..min(column, j + 2) {
206 if board_of_game[m][n] < 10 {
207 flag = false;
208 }
209 }
210 }
211 if flag {
212 unknow_block += 1;
213 }
214 } else if board_of_game[i][j] == 11 {
215 is_minenum += 1;
216 }
217 }
218 }
219 let mut p = 0; while !all_cell.is_empty() {
222 matrix_xs.push(vec![]);
223 matrix_bs.push(vec![]);
224 let x_0 = all_cell[0].0;
225 let y_0 = all_cell[0].1;
226 let mut num_cells = vec![]; let mut temp_cells = vec![]; let mut flag_num = 0;
229 for m in max(1, x_0) - 1..min(row, x_0 + 2) {
230 for n in max(1, y_0) - 1..min(column, y_0 + 2) {
231 if board_of_game[m][n] == 10 {
232 matrix_xs[p].push((m, n));
233 }
234 if board_of_game[m][n] == 11 {
235 flag_num += 1;
236 }
237 }
238 }
239 matrix_bs[p].push(board_of_game[x_0][y_0] - flag_num);
240 num_cells.push((x_0, y_0));
241 temp_cells.push((x_0, y_0));
242 while !temp_cells.is_empty() {
243 let x_e = temp_cells[0].0;
244 let y_e = temp_cells[0].1;
245 temp_cells.remove(0);
246 for t in (1..all_cell.len()).rev() {
247 let x_t = all_cell[t].0;
249 let y_t = all_cell[t].1;
250 if x_t >= x_e + 3 || x_e >= x_t + 3 || y_t >= y_e + 3 || y_e >= y_t + 3 {
251 continue;
252 }
253 let mut flag_be_neighbor = false;
254 for m in max(1, max(x_t, x_e)) - 1..min(row, min(x_t + 2, x_e + 2)) {
255 for n in max(1, max(y_t, y_e)) - 1..min(column, min(y_t + 2, y_e + 2)) {
256 if board_of_game[m][n] == 10 {
257 flag_be_neighbor = true;
258 break;
259 }
260 }
261 } if flag_be_neighbor {
263 let mut flag_num = 0;
264 for m in max(1, x_t) - 1..min(row, x_t + 2) {
265 for n in max(1, y_t) - 1..min(column, y_t + 2) {
266 if board_of_game[m][n] == 10 {
267 if !matrix_xs[p].contains(&(m, n)) {
268 matrix_xs[p].push((m, n));
269 }
270 }
271 if board_of_game[m][n] == 11 {
272 flag_num += 1;
273 }
274 }
275 }
276 matrix_bs[p].push(board_of_game[x_t][y_t] - flag_num);
277 num_cells.push((x_t, y_t));
278 temp_cells.push(all_cell[t]);
279 all_cell.remove(t);
280 }
281 }
282 }
283 matrix_as.push(vec![vec![0; matrix_xs[p].len()]; matrix_bs[p].len()]);
284 for i in 0..num_cells.len() {
285 for j in 0..matrix_xs[p].len() {
286 if num_cells[i].0 <= matrix_xs[p][j].0 + 1
287 && matrix_xs[p][j].0 <= num_cells[i].0 + 1
288 && num_cells[i].1 <= matrix_xs[p][j].1 + 1
289 && matrix_xs[p][j].1 <= num_cells[i].1 + 1
290 {
291 matrix_as[p][i][j] = 1;
292 }
293 }
294 }
295 all_cell.remove(0);
296 p += 1;
297 }
298 (matrix_as, matrix_xs, matrix_bs, unknow_block, is_minenum)
299}
300
301pub fn refresh_matrixses(
303 board_of_game: &Vec<Vec<i32>>,
304) -> (
305 Vec<Vec<Vec<Vec<i32>>>>,
306 Vec<Vec<Vec<(usize, usize)>>>,
307 Vec<Vec<Vec<i32>>>,
308) {
309 let row = board_of_game.len();
310 let column = board_of_game[0].len();
311 let mut Ases = vec![];
312 let mut xses = vec![];
313 let mut bses = vec![];
314 let (mut As, mut xs, mut bs, _, _) = refresh_matrixs(board_of_game);
315 if As.len() == 1 {
316 return (vec![As], vec![xs], vec![bs]);
318 }
319 let mut adjacency_matrix = vec![vec![false; As.len()]; As.len()];
321 let mut board_mark = board_of_game.clone();
323 let mut cell_10 = vec![];
324 for i in 0..row {
325 for j in 0..column {
326 if board_mark[i][j] == 10 {
327 board_mark[i][j] = 21;
328 let mut flag_c = false;
329 let mut buffer = vec![];
330 buffer.push((i, j));
331 while !buffer.is_empty() {
333 let (t_i, t_j) = buffer.pop().unwrap();
334 let mut flag_is_side = false;
335 for m in max(1, t_i) - 1..min(row, t_i + 2) {
336 for n in max(1, t_j) - 1..min(column, t_j + 2) {
337 if board_mark[m][n] == 10 {
338 board_mark[m][n] = 21;
339 buffer.push((m, n));
340 } else if board_mark[m][n] < 10 {
341 flag_is_side = true;
342 }
343 }
344 }
345 if flag_is_side {
346 if !flag_c {
347 cell_10.push(vec![]);
348 flag_c = true;
349 }
350 cell_10.last_mut().unwrap().push((t_i, t_j));
351 }
352 }
353 } else {
354 continue;
355 }
356 }
357 }
358 if cell_10.len() == 1 {
360 return (vec![As], vec![xs], vec![bs]);
362 }
363 for mut block in cell_10 {
364 let mut seed_id = -1;
365 while !block.is_empty() {
366 let seed = block.pop().unwrap();
367 let t = xs.iter().position(|r| r.contains(&seed)).unwrap();
368 if seed_id >= 0 {
369 adjacency_matrix[seed_id as usize][t] = true;
370 adjacency_matrix[t][seed_id as usize] = true;
371 }
372 seed_id = t as i32;
373 block.retain(|x| !xs[seed_id as usize].contains(x))
374 }
375 } for i in 0..As.len() {
377 if As[i].is_empty() {
378 continue;
379 }
380 Ases.push(vec![]);
381 xses.push(vec![]);
382 bses.push(vec![]);
383 let mut buffer = vec![i];
384
385 while !buffer.is_empty() {
386 let t = buffer.pop().unwrap();
387 Ases.last_mut().unwrap().push(vec![]);
388 Ases.last_mut()
389 .unwrap()
390 .last_mut()
391 .unwrap()
392 .append(&mut As[t]);
393 xses.last_mut().unwrap().push(vec![]);
394 xses.last_mut()
395 .unwrap()
396 .last_mut()
397 .unwrap()
398 .append(&mut xs[t]);
399 bses.last_mut().unwrap().push(vec![]);
400 bses.last_mut()
401 .unwrap()
402 .last_mut()
403 .unwrap()
404 .append(&mut bs[t]);
405 for idj in t..As.len() {
406 if adjacency_matrix[t][idj] {
407 buffer.push(idj);
408 }
409 }
410 }
411 }
412 (Ases, xses, bses)
413}
414
415#[cfg(feature = "js")]
418pub fn get_random_int(limit: usize) -> usize {
419 if limit == 0 {
420 return 0;
421 }
422 let mut a = [0, 0, 0, 0];
423 let mut t;
424 loop {
425 getrandom(&mut a).unwrap();
426 t = (a[0] as usize) << 24 ^ (a[1] as usize) << 16 ^ (a[2] as usize) << 8 ^ (a[3] as usize);
428 if t < (0b11111111_11111111_11111111_11111111 / limit * limit) {
429 break;
430 }
431 }
432 t % limit
433}
434
435#[cfg(feature = "js")]
436pub trait js_shuffle {
437 fn shuffle_(&mut self);
438}
439
440#[cfg(feature = "js")]
441impl js_shuffle for Vec<i32> {
442 fn shuffle_(&mut self) {
443 let l = self.len();
445 for i in 1..l {
446 let id = get_random_int(i + 1);
447 let t = self[i];
448 self[i] = self[id];
449 self[id] = t;
450 }
451 }
452}
453
454pub fn get_board_1d(area: usize, minenum: usize) -> Vec<i32> {
458 let mut board_1d: Vec<i32> = vec![];
459 board_1d.reserve(area);
460 board_1d = vec![0; area - minenum];
461 board_1d.append(&mut vec![-1; minenum]);
462 #[cfg(any(feature = "py", feature = "rs"))]
463 let mut rng = thread_rng();
464
465 #[cfg(any(feature = "py", feature = "rs"))]
466 board_1d.shuffle(&mut rng);
467
468 #[cfg(feature = "js")]
469 board_1d.shuffle_();
470 board_1d
471}
472
473pub fn trans_board_1d_2d_op(
475 board_1d: &Vec<i32>,
476 row: usize,
477 column: usize,
478 x0: usize,
479 y0: usize,
480) -> Vec<Vec<i32>> {
481 let mut board = vec![vec![0; column]; row];
482 let mut i = 0;
483 for x in 0..row {
484 for y in 0..column {
485 if x <= x0 + 1 && x0 <= x + 1 && y <= y0 + 1 && y0 <= y + 1 {
486 continue;
487 }
488 if board_1d[i] < 0 {
489 board[x][y] = -1;
490 for j in max(1, x) - 1..min(row, x + 2) {
491 for k in max(1, y) - 1..min(column, y + 2) {
492 if board[j][k] >= 0 {
493 board[j][k] += 1
494 }
495 }
496 }
497 }
498 i += 1;
499 }
500 }
501 board
502}
503
504pub fn laymine(row: usize, column: usize, minenum: usize, x0: usize, y0: usize) -> Vec<Vec<i32>> {
508 let board1_dim = get_board_1d(row * column - 1, minenum);
509
510 let mut board1_dim_2: Vec<i32> = vec![];
511 board1_dim_2.reserve(row * column);
512 let pointer = x0 + y0 * row;
513 for i in 0..pointer {
514 board1_dim_2.push(board1_dim[i]);
515 }
516 board1_dim_2.push(0);
517 for i in pointer..(row * column - 1) {
518 board1_dim_2.push(board1_dim[i]);
519 }
520 let mut board: Vec<Vec<i32>> = vec![vec![0; column]; row];
521 for i in 0..(row * column) {
522 if board1_dim_2[i] < 0 {
523 let x = i % row;
524 let y = i / row;
525 board[x][y] = -1;
526 for j in max(1, x) - 1..min(row, x + 2) {
527 for k in max(1, y) - 1..min(column, y + 2) {
528 if board[j][k] >= 0 {
529 board[j][k] += 1;
530 }
531 }
532 }
533 }
534 }
535 board
536}
537
538pub fn laymine_op(
542 row: usize,
543 column: usize,
544 minenum: usize,
545 x0: usize,
546 y0: usize,
547) -> Vec<Vec<i32>> {
548 let mut area_op = 9;
549 if x0 == 0 || y0 == 0 || x0 == row - 1 || y0 == column - 1 {
550 if x0 == 0 && y0 == 0
551 || x0 == 0 && y0 == column - 1
552 || x0 == row - 1 && y0 == 0
553 || x0 == row - 1 && y0 == column - 1
554 {
555 area_op = 4;
556 } else {
557 area_op = 6;
558 }
559 }
560 let area = row * column - area_op;
561 let board_1d = get_board_1d(area, minenum);
562 trans_board_1d_2d_op(&board_1d, row, column, x0, y0)
563}
564
565pub fn cal_bbbv_on_island<T>(board: &T) -> usize
566where
567 T: std::ops::Index<usize> + safe_board::BoardSize,
568 T::Output: std::ops::Index<usize, Output = i32>,
569{
570 let row = board.get_row();
572 let column = board.get_column();
573 let mut Num3BVonIsland = 0;
574 for i in 0..row {
575 for j in 0..column {
576 if board[i][j] > 0 {
577 let mut flag: bool = true;
578 for x in max(1, i) - 1..min(row, i + 2) {
579 for y in max(1, j) - 1..min(column, j + 2) {
580 if board[x][y] == 0 {
581 flag = false;
582 }
583 }
584 }
585 if flag {
586 Num3BVonIsland += 1;
587 }
588 }
589 }
590 }
591 Num3BVonIsland
592}
593
594pub fn cal_bbbv<T>(board: &T) -> usize
596where
597 T: std::ops::Index<usize> + safe_board::BoardSize,
598 T::Output: std::ops::Index<usize, Output = i32>,
599{
600 cal_bbbv_on_island(board) + cal_op(board)
601}
602
603pub fn refresh_board<T>(
606 board: &T,
607 boardofGame: &mut Vec<Vec<i32>>,
608 mut clicked_poses: Vec<(usize, usize)>,
609) where
610 T: std::ops::Index<usize> + safe_board::BoardSize,
611 T::Output: std::ops::Index<usize, Output = i32>,
612{
613 let row = board.get_row();
614 let column = board.get_column();
615 let mut loss_flag = false;
617 while let Some(top) = clicked_poses.pop() {
618 let (i, j) = top;
619 if board[i][j] > 0 {
620 boardofGame[i][j] = board[i][j];
621 } else if board[i][j] == 0 {
622 boardofGame[i][j] = 0;
623 for m in max(1, i) - 1..min(row, i + 2) {
624 for n in max(1, j) - 1..min(column, j + 2) {
625 if (i != m || j != n) && (boardofGame[m][n] == 10 || boardofGame[m][n] == 12) {
626 clicked_poses.push((m, n));
627 }
628 }
629 }
630 } else {
631 boardofGame[i][j] = 15; loss_flag = true;
633 }
634 }
635 if loss_flag {
637 for i in 0..row {
638 for j in 0..column {
639 if boardofGame[i][j] == 11 && board[i][j] != -1 {
640 boardofGame[i][j] = 14; }
642 }
643 }
644 }
645}
646
647#[derive(Clone, Debug)]
648pub struct BigNumber {
649 pub a: f64,
652 pub b: i32,
653}
654
655impl BigNumber {
656 fn a_become_smaller_than(&mut self, thrd: f64) {
657 if self.a < thrd {
660 return;
661 }
662 while self.a >= 10.0 {
663 self.a /= 10.0;
664 self.b += 1;
665 }
666 }
667 pub fn mul_usize(&mut self, k: usize) {
668 if k == 0 {
670 self.a = 0.0;
671 self.b = 1;
672 } else {
673 self.a *= k as f64;
674 self.a_become_smaller_than(10.0);
675 }
676 }
677 pub fn mul_big_number(&mut self, k: &BigNumber) {
678 self.a *= k.a;
680 self.b += k.b;
681 self.a_become_smaller_than(10.0);
682 }
683 pub fn add_big_number(&mut self, k: &BigNumber) {
684 let mut ka = k.a;
685 let mut kb = k.b;
686 while self.b > kb {
687 ka /= 10.0;
688 kb += 1;
689 }
690 while self.b < kb {
691 self.a /= 10.0;
692 self.b += 1;
693 }
694 self.a += ka;
695 self.a_become_smaller_than(10.0);
696 }
697 pub fn div_big_num(&mut self, k: &BigNumber) -> f64 {
698 let mut ans = self.a / k.a;
700 while self.b < k.b {
701 ans /= 10.0;
702 self.b += 1;
703 }
704 while self.b > k.b {
705 ans *= 10.0;
706 self.b -= 1;
707 }
708 ans
709 }
710 pub fn div_usize(&mut self, k: usize) {
711 if self.a < 1e-8 && self.b == 1 {
713 return;
714 } else {
715 self.a /= k as f64;
716 while self.a < 1.0 {
717 self.a *= 10.0;
718 self.b -= 1;
719 }
720 }
721 }
722}
723
724pub fn C(n: usize, k: usize) -> BigNumber {
725 if n < k + k {
727 return C(n, n - k);
728 };
729 let maximum_limit: f64 = 1e208;
730 let mut c = BigNumber { a: 1.0, b: 0 };
731 for i in 0..k {
732 c.a *= (n - i) as f64;
733 c.a /= (i + 1) as f64;
734 c.a_become_smaller_than(maximum_limit);
735 }
736 c.a_become_smaller_than(10.0);
737 c
738}
739
740pub fn C_query<T, U>(n: T, k: U) -> usize
741where
742 T: Into<usize>,
743 U: Into<usize>,
744{
745 let a = [
747 [1, 0, 0, 0, 0, 0, 0, 0, 0],
748 [1, 1, 0, 0, 0, 0, 0, 0, 0],
749 [1, 2, 1, 0, 0, 0, 0, 0, 0],
750 [1, 3, 3, 1, 0, 0, 0, 0, 0],
751 [1, 4, 6, 4, 1, 0, 0, 0, 0],
752 [1, 5, 10, 10, 5, 1, 0, 0, 0],
753 [1, 6, 15, 20, 15, 6, 1, 0, 0],
754 [1, 7, 21, 35, 35, 21, 7, 1, 0],
755 [1, 8, 28, 56, 70, 56, 28, 8, 1],
756 ];
757 a[n.into()][k.into()]
758}
759
760pub fn combine(
761 MatrixA: &Vec<Vec<i32>>,
762 Matrixx: &Vec<(usize, usize)>,
763) -> (Vec<Vec<i32>>, Vec<(usize, usize)>, Vec<Vec<usize>>) {
764 let mut matrixA_squeeze = MatrixA.clone();
768 let mut matrixx_squeeze = Matrixx.clone();
769 let cells_num = matrixx_squeeze.len();
770 let mut pair_cells = vec![];
771 let mut del_cells = vec![]; for i in 0..cells_num {
773 pair_cells.push(vec![i]);
774 for j in i + 1..cells_num {
775 if !matrixA_squeeze.iter().any(|x| x[i] != x[j]) {
776 pair_cells[i].push(j);
777 del_cells.push(j);
778 }
779 }
780 }
781 del_cells.sort_by(|a, b| b.cmp(&a));
782 del_cells.dedup();
783 for i in del_cells {
784 for r in 0..matrixA_squeeze.len() {
785 matrixA_squeeze[r].remove(i);
786 }
787 matrixx_squeeze.remove(i);
788 pair_cells.remove(i);
789 }
790 let cell_squeeze_num = pair_cells.len();
791 for i in 0..cell_squeeze_num {
792 let k = pair_cells[i].len() as i32;
793 for r in 0..matrixA_squeeze.len() {
794 matrixA_squeeze[r][i] *= k;
795 }
796 }
797 (matrixA_squeeze, matrixx_squeeze, pair_cells)
798}
799
800
801pub fn cal_all_solution(
803 matrixA: &Vec<Vec<i32>>,
804 Matrixb: &Vec<i32>,
805) -> Vec<Vec<u8>> {
806 let column = matrixA[0].len();
807 let row = matrixA.len();
808 let mut enum_comb_table: Vec<Vec<u8>> = vec![vec![0; column]];
809 let mut not_enum_cell: Vec<bool> = vec![true; column]; let mut enum_cell_table: Vec<Vec<usize>> = vec![];
811 for row in 0..row {
812 let mut new_enum_cell = vec![]; let mut enum_cell = vec![]; let mut new_enum_max = vec![];
815 for j in 0..column {
816 if matrixA[row][j] > 0 {
817 enum_cell.push(j);
818 if not_enum_cell[j] {
819 not_enum_cell[j] = false;
820 new_enum_cell.push(j);
821 new_enum_max.push(matrixA[row][j]);
822 }
823 }
824 }
825 let mut new_enum_table = (0..new_enum_cell.len())
827 .map(|i| 0..new_enum_max[i] + 1)
828 .multi_cartesian_product()
829 .collect::<Vec<_>>();
830 new_enum_table.retain(|x| x.iter().sum::<i32>() <= Matrixb[row]);
831 if new_enum_table.is_empty() {
833 enum_comb_table.retain(|item| {
834 enum_cell
835 .iter()
836 .fold(0, |sum: u8, i: &usize| sum + item[*i])
837 == Matrixb[row] as u8
838 });
839 } else {
841 let mut flag_1 = true; let enum_comb_table_len = enum_comb_table.len();
843 for item in new_enum_table {
844 if flag_1 {
845 for m in 0..new_enum_cell.len() {
846 for n in 0..enum_comb_table_len {
847 enum_comb_table[n][new_enum_cell[m]] = item[m] as u8;
848 }
849 }
850 flag_1 = false;
851 } else {
852 for n in 0..enum_comb_table_len {
853 let mut one_row_in_new_table = enum_comb_table[n].clone();
854 for m in 0..new_enum_cell.len() {
855 one_row_in_new_table[new_enum_cell[m]] = item[m] as u8;
856 }
857 enum_comb_table.push(one_row_in_new_table);
858 }
859 }
860 } let mut equations = vec![];
862 for kk in &enum_cell {
863 for rr in 0..row {
864 if matrixA[rr][*kk] > 0 {
865 equations.push(rr);
866 }
867 }
868 }
869 equations.dedup();
870 for equ in equations {
872 enum_comb_table.retain(|item| {
873 enum_cell_table[equ]
874 .iter()
875 .fold(0, |sum: u8, i: &usize| sum + item[*i])
876 == Matrixb[equ] as u8
877 });
878 }
879 enum_comb_table.retain(|item| {
880 enum_cell
881 .iter()
882 .fold(0, |sum: u8, i: &usize| sum + item[*i])
883 == Matrixb[row] as u8
884 }); }
887 enum_cell_table.push(enum_cell);
888 }
889 enum_comb_table
890}
891
892fn cal_cell_and_equation_map(matrix_a: &Vec<Vec<i32>>) -> (Vec<Vec<usize>>, Vec<Vec<usize>>) {
1038 let cells_num = matrix_a[0].len();
1042 let equations_num = matrix_a.len();
1043 let mut cell_to_equation_map = vec![vec![]; cells_num];
1044 let mut equation_to_cell_map = vec![vec![]; equations_num];
1045 for i in 0..equations_num {
1046 for j in 0..cells_num {
1047 if matrix_a[i][j] >= 1 {
1048 equation_to_cell_map[i].push(j);
1049 cell_to_equation_map[j].push(i);
1050 }
1051 }
1052 }
1053 (cell_to_equation_map, equation_to_cell_map)
1054}
1055
1056fn cal_table_minenum_recursion_step(
1057 idx: usize,
1058 current_amount: usize,
1059 table_minenum: &mut [Vec<usize>; 2],
1060 table_cell_minenum: &mut Vec<Vec<usize>>,
1061 matrixA_squeeze: &Vec<Vec<i32>>,
1064 matrix_b: &Vec<i32>,
1065 matrix_b_remain: &mut Vec<i32>,
1066 combination_relationship: &Vec<Vec<usize>>,
1067 cell_to_equation_map: &Vec<Vec<usize>>,
1068 equation_to_cell_map: &Vec<Vec<usize>>,
1069 mine_vec: &mut Vec<usize>,
1070) -> Result<bool, usize> {
1071 let cells_num = matrixA_squeeze[0].len();
1073 if idx >= cells_num {
1074 let total_mines_num: usize = mine_vec.iter().sum();
1076 if total_mines_num >= table_minenum[1].len() {
1077 return Err(5);
1078 }
1079 table_minenum[1][total_mines_num] += current_amount;
1080 for (idn, n) in mine_vec.iter().enumerate() {
1081 table_cell_minenum[total_mines_num][idn] +=
1082 current_amount * n / combination_relationship[idn].len();
1083 }
1084 return Ok(true);
1085 }
1086
1087 let mut upper_limit = combination_relationship[idx].len();
1088 let mut lower_limit = 0usize;
1089 for cell_i in &cell_to_equation_map[idx] {
1090 if matrixA_squeeze[*cell_i][idx] == 0 {
1091 continue;
1092 }
1093 let upper_limit_i = min(
1094 matrix_b_remain[*cell_i],
1095 combination_relationship[idx].len() as i32,
1096 );
1097 let mut lower_limit_i = matrix_b_remain[*cell_i];
1098 for j in &equation_to_cell_map[*cell_i] {
1099 if j > &idx {
1100 lower_limit_i -= combination_relationship[*j].len() as i32;
1101 }
1102 }
1103 if upper_limit_i < upper_limit as i32 {
1104 upper_limit = upper_limit_i as usize;
1105 }
1106 if lower_limit_i > lower_limit as i32 {
1107 lower_limit = lower_limit_i as usize;
1108 }
1109 }
1110
1111 for u in lower_limit..upper_limit + 1 {
1114 mine_vec[idx] = u;
1116 if u > 0 {
1117 for tt in &cell_to_equation_map[idx] {
1118 matrix_b_remain[*tt] -= u as i32;
1119 }
1120 }
1121 let _ = cal_table_minenum_recursion_step(
1122 idx + 1,
1123 current_amount * C_query(combination_relationship[idx].len(), u),
1124 table_minenum,
1125 table_cell_minenum,
1126 &matrixA_squeeze,
1127 &matrix_b,
1128 matrix_b_remain,
1129 &combination_relationship,
1130 &cell_to_equation_map,
1131 &equation_to_cell_map,
1132 mine_vec,
1133 )?;
1134 for tt in &cell_to_equation_map[idx] {
1135 matrix_b_remain[*tt] += u as i32;
1136 }
1137 mine_vec[idx] = 0;
1138 }
1139 Ok(false)
1141}
1142
1143pub fn cal_table_minenum_recursion(
1144 matrixA_squeeze: &Vec<Vec<i32>>,
1145 matrixx_squeeze: &Vec<(usize, usize)>,
1146 matrix_b: &Vec<i32>,
1147 combination_relationship: &Vec<Vec<usize>>,
1148) -> Result<([Vec<usize>; 2], Vec<Vec<usize>>), usize> {
1149 let cells_num = matrixx_squeeze.len();
1153 if cells_num > ENUM_LIMIT {
1154 return Err(cells_num);
1156 }
1157 let cells_num_total = combination_relationship
1158 .iter()
1159 .fold(0, |item, x| item + x.len());
1160 let mut flag_legal_board = true;
1163 let mut table_minenum: [Vec<usize>; 2] = [
1164 (0..cells_num_total + 1).collect::<Vec<usize>>(),
1165 vec![0; cells_num_total + 1],
1166 ];
1167 let (cell_to_equation_map, equation_to_cell_map) = cal_cell_and_equation_map(&matrixA_squeeze);
1168 let mut table_cell_minenum: Vec<Vec<usize>> = vec![vec![0; cells_num]; cells_num_total + 1];
1172
1173 cal_table_minenum_recursion_step(
1175 0,
1176 1,
1177 &mut table_minenum,
1178 &mut table_cell_minenum,
1179 &matrixA_squeeze,
1180 &matrix_b,
1181 &mut matrix_b.clone(),
1182 &combination_relationship,
1183 &cell_to_equation_map,
1184 &equation_to_cell_map,
1185 &mut (vec![0; cells_num]),
1186 )?;
1187 while table_minenum[1][0] == 0 {
1190 table_minenum[0].remove(0);
1191 table_minenum[1].remove(0);
1192 table_cell_minenum.remove(0);
1193 if table_cell_minenum.is_empty() {
1194 flag_legal_board = false;
1195 break;
1196 }
1197 }
1198 if flag_legal_board {
1199 while table_minenum[1][table_cell_minenum.len() - 1] == 0 {
1200 table_minenum[0].pop();
1201 table_minenum[1].pop();
1202 table_cell_minenum.pop();
1203 }
1204 }
1205 if flag_legal_board {
1206 Ok((table_minenum, table_cell_minenum))
1207 } else {
1208 return Err(1);
1209 }
1210}
1211
1212pub fn unsolvable_structure(BoardCheck: &Vec<Vec<i32>>) -> bool {
1300 let row = BoardCheck.len();
1301 let column = BoardCheck[0].len();
1302 let mut Board = vec![vec![0; column]; row];
1303 for i in 0..row {
1304 for j in 0..column {
1305 if BoardCheck[i][j] == -1 {
1306 Board[i][j] = -1;
1307 }
1308 }
1309 }
1310 for i in 0..row - 2 {
1311 if i < row - 3 {
1313 if Board[i][0] == -1
1314 && Board[i][1] == -1
1315 && Board[i + 3][0] == -1
1316 && Board[i + 3][1] == -1
1317 && Board[i + 1][0] + Board[i + 2][0] == -1
1318 || Board[i][column - 1] == -1
1319 && Board[i][column - 2] == -1
1320 && Board[i + 3][column - 1] == -1
1321 && Board[i + 3][column - 2] == -1
1322 && Board[i + 1][column - 1] + Board[i + 2][column - 1] == -1
1323 {
1324 return true;
1325 }
1326 }
1327 if Board[i][2] == -1
1328 && Board[i + 1][2] == -1
1329 && Board[i + 2][2] == -1
1330 && Board[i + 1][0] + Board[i + 1][1] == -1
1331 || Board[i][column - 3] == -1
1332 && Board[i + 1][column - 3] == -1
1333 && Board[i + 2][column - 3] == -1
1334 && Board[i + 1][column - 1] + Board[i + 1][column - 2] == -1
1335 || Board[i][0] == -1
1336 && Board[i][1] == -1
1337 && Board[i + 1][1] == -1
1338 && Board[i + 2][1] == -1
1339 && Board[i + 2][0] == -1
1340 && Board[i + 1][0] == 0
1341 || Board[i][column - 1] == -1
1342 && Board[i][column - 2] == -1
1343 && Board[i + 1][column - 2] == -1
1344 && Board[i + 2][column - 2] == -1
1345 && Board[i + 2][column - 1] == -1
1346 && Board[i + 1][column - 1] == 0
1347 {
1348 return true;
1349 }
1350 if i < row - 3 {
1351 if Board[i][2] == -1
1352 && Board[i + 3][2] == -1
1353 && Board[i + 1][0] + Board[i + 1][1] == -1
1354 && Board[i + 1][1] + Board[i + 2][1] == -1
1355 && Board[i + 2][1] + Board[i + 2][0] == -1
1356 || Board[i][column - 3] == -1
1357 && Board[i + 3][column - 3] == -1
1358 && Board[i + 1][column - 1] + Board[i + 1][column - 2] == -1
1359 && Board[i + 1][column - 2] + Board[i + 2][column - 2] == -1
1360 && Board[i + 2][column - 2] + Board[i + 2][column - 1] == -1
1361 {
1362 return true;
1363 }
1364 }
1365 }
1366 for j in 0..column - 2 {
1367 if j < column - 3 {
1369 if Board[0][j] == -1
1370 && Board[1][j] == -1
1371 && Board[0][j + 3] == -1
1372 && Board[1][j + 3] == -1
1373 && Board[0][j + 1] + Board[0][j + 2] == -1
1374 || Board[row - 1][j] == -1
1375 && Board[row - 2][j] == -1
1376 && Board[row - 1][j + 3] == -1
1377 && Board[row - 2][j + 3] == -1
1378 && Board[row - 1][j + 1] + Board[row - 1][j + 2] == -1
1379 {
1380 return true;
1381 }
1382 }
1383 if Board[2][j] == -1
1384 && Board[2][j + 1] == -1
1385 && Board[2][j + 2] == -1
1386 && Board[0][j + 1] + Board[1][j + 1] == -1
1387 || Board[row - 3][j] == -1
1388 && Board[row - 3][j + 1] == -1
1389 && Board[row - 3][j + 2] == -1
1390 && Board[row - 1][j + 1] + Board[row - 2][j + 1] == -1
1391 || Board[0][j] == -1
1392 && Board[1][j] == -1
1393 && Board[1][j + 1] == -1
1394 && Board[1][j + 2] == -1
1395 && Board[0][j + 2] == -1
1396 && Board[0][j + 1] == 0
1397 || Board[row - 1][j] == -1
1398 && Board[row - 2][j] == -1
1399 && Board[row - 2][j + 1] == -1
1400 && Board[row - 2][j + 2] == -1
1401 && Board[row - 1][j + 2] == -1
1402 && Board[row - 1][j + 1] == 0
1403 {
1404 return true;
1405 }
1406 if j < column - 3 {
1407 if Board[2][j] == -1
1408 && Board[2][j + 3] == -1
1409 && Board[0][j + 1] + Board[1][j + 1] == -1
1410 && Board[1][j + 1] + Board[1][j + 2] == -1
1411 && Board[1][j + 2] + Board[0][j + 2] == -1
1412 || Board[row - 3][j] == -1
1413 && Board[row - 3][j + 3] == -1
1414 && Board[row - 1][j + 1] + Board[row - 2][j + 1] == -1
1415 && Board[row - 2][j + 1] + Board[row - 2][j + 2] == -1
1416 && Board[row - 2][j + 2] + Board[row - 1][j + 2] == -1
1417 {
1418 return true;
1419 }
1420 }
1421 }
1422 if Board[0][2] == -1 && Board[1][2] == -1 && Board[0][0] + Board[0][1] == -1
1423 || Board[2][0] == -1 && Board[2][1] == -1 && Board[0][0] + Board[1][0] == -1
1424 || Board[0][column - 3] == -1
1425 && Board[1][column - 3] == -1
1426 && Board[0][column - 1] + Board[0][column - 2] == -1
1427 || Board[2][column - 1] == -1
1428 && Board[2][column - 2] == -1
1429 && Board[0][column - 1] + Board[1][column - 1] == -1
1430 || Board[row - 1][2] == -1
1431 && Board[row - 2][2] == -1
1432 && Board[row - 1][0] + Board[row - 1][1] == -1
1433 || Board[row - 3][0] == -1
1434 && Board[row - 3][1] == -1
1435 && Board[row - 1][0] + Board[row - 2][0] == -1
1436 || Board[row - 1][column - 3] == -1
1437 && Board[row - 2][column - 3] == -1
1438 && Board[row - 1][column - 1] + Board[row - 1][column - 2] == -1
1439 || Board[row - 3][column - 1] == -1
1440 && Board[row - 3][column - 2] == -1
1441 && Board[row - 1][column - 1] + Board[row - 2][column - 1] == -1
1442 || Board[0][1] + Board[1][1] + Board[1][0] == -3 && Board[0][0] == 0
1443 || Board[0][column - 2] + Board[1][column - 2] + Board[1][column - 1] == -3
1444 && Board[0][column - 1] == 0
1445 || Board[row - 1][column - 2] + Board[row - 2][column - 2] + Board[row - 2][column - 1]
1446 == -3
1447 && Board[row - 1][column - 1] == 0
1448 || Board[row - 1][1] + Board[row - 2][1] + Board[row - 2][0] == -3 && Board[row - 1][0] == 0
1449 || Board[2][2] == -1 && Board[0][1] + Board[1][1] == -1 && Board[1][0] + Board[1][1] == -1
1450 || Board[row - 3][2] == -1
1451 && Board[row - 1][1] + Board[row - 2][1] == -1
1452 && Board[row - 2][0] + Board[row - 2][1] == -1
1453 || Board[row - 3][column - 3] == -1
1454 && Board[row - 1][column - 2] + Board[row - 2][column - 2] == -1
1455 && Board[row - 2][column - 1] + Board[row - 2][column - 2] == -1
1456 || Board[2][column - 3] == -1
1457 && Board[0][column - 2] + Board[1][column - 2] == -1
1458 && Board[1][column - 1] + Board[1][column - 2] == -1
1459 {
1460 return true;
1462 }
1463 for i in 0..row - 2 {
1464 for j in 0..column - 2 {
1466 if j < column - 3 {
1467 if Board[i][j] == -1
1468 && Board[i + 1][j] == -1
1469 && Board[i + 2][j] == -1
1470 && Board[i][j + 3] == -1
1471 && Board[i + 1][j + 3] == -1
1472 && Board[i + 2][j + 3] == -1
1473 && Board[i + 1][j + 1] + Board[i + 1][j + 2] == -1
1474 {
1475 return true;
1476 }
1477 }
1478 if i < row - 3 {
1479 if Board[i][j] == -1
1480 && Board[i][j + 1] == -1
1481 && Board[i][j + 2] == -1
1482 && Board[i + 3][j] == -1
1483 && Board[i + 3][j + 1] == -1
1484 && Board[i + 3][j + 2] == -1
1485 && Board[i + 1][j + 1] + Board[i + 2][j + 1] == -1
1486 {
1487 return true;
1488 }
1489 }
1490 if Board[i][j] == -1
1491 && Board[i + 1][j] == -1
1492 && Board[i + 2][j] == -1
1493 && Board[i][j + 1] == -1
1494 && Board[i + 2][j + 1] == -1
1495 && Board[i][j + 2] == -1
1496 && Board[i + 1][j + 2] == -1
1497 && Board[i + 2][j + 2] == -1
1498 && Board[i + 1][j + 1] == 0
1499 {
1500 return true;
1501 }
1502 if j < column - 3 && i < row - 3 {
1503 if Board[i][j] == -1
1504 && Board[i + 3][j] == -1
1505 && Board[i][j + 3] == -1
1506 && Board[i + 3][j + 3] == -1
1507 && Board[i + 1][j + 1] + Board[i + 2][j + 1] == -1
1508 && Board[i + 1][j + 1] + Board[i + 1][j + 2] == -1
1509 && Board[i + 2][j + 1] + Board[i + 2][j + 2] == -1
1510 {
1511 return true;
1512 }
1513 }
1514 }
1515 }
1516 false
1517}
1518
1519pub fn cal_bbbv_exp(Board: &Vec<Vec<i32>>) -> usize {
1521 let mut board = Board.clone();
1522 let mut op_id = 0;
1523 let mut op_list = [false; 200];
1524 let mut bv = 0;
1525 for x in 0..16 {
1526 for y in 0..30 {
1527 if board[x][y] > 0 {
1528 board[x][y] = 1000000;
1529 bv += 1;
1530 } else if board[x][y] == 0 {
1531 let mut min_op_id = 1000;
1532 let mut flag_op = false; if x >= 1 {
1534 for j in max(1, y) - 1..min(30, y + 2) {
1535 if board[x - 1][j] > 999999 {
1536 board[x - 1][j] = 1;
1537 bv -= 1;
1538 } else if Board[x - 1][j] == 0 {
1539 if board[x - 1][j] < min_op_id {
1540 if flag_op {
1541 op_list[min_op_id as usize] = false;
1542 } else {
1543 flag_op = true;
1544 }
1545 min_op_id = board[x - 1][j];
1546 }
1547 }
1548 }
1549 }
1550 if y >= 1 {
1551 if board[x][y - 1] > 999999 {
1552 board[x][y - 1] = 1;
1553 bv -= 1;
1554 } else if Board[x][y - 1] == 0 {
1555 if board[x][y - 1] < min_op_id {
1556 if flag_op {
1557 op_list[min_op_id as usize] = false;
1558 } else {
1559 flag_op = true;
1560 }
1561 min_op_id = board[x][y - 1];
1562 }
1563 }
1564 }
1565 if !flag_op {
1566 op_id += 1;
1567 op_list[op_id as usize] = true;
1568 }
1569 }
1570 }
1571 }
1572 for x in (0..16).rev() {
1573 for y in (0..30).rev() {
1574 if board[x][y] == 0 {
1575 if x <= 14 {
1576 for j in max(1, y) - 1..min(30, y + 2) {
1577 if board[x + 1][j] > 999999 {
1578 board[x + 1][j] = 1;
1579 bv -= 1;
1580 } else if Board[x + 1][j] == 0 {
1581 if board[x + 1][j] < board[x][y] {
1582 op_list[board[x][y] as usize] = false;
1583 board[x][y] = board[x + 1][j];
1584 }
1585 }
1586 }
1587 }
1588 if y <= 28 {
1589 if board[x][y + 1] > 999999 {
1590 board[x][y + 1] = 1;
1591 bv -= 1;
1592 } else if Board[x][y + 1] == 0 {
1593 if board[x][y + 1] < board[x][y] {
1594 op_list[board[x][y] as usize] = false;
1595 board[x][y] = board[x][y + 1];
1596 }
1597 }
1598 }
1599 }
1600 }
1601 }
1602 for i in 0..op_id + 1 {
1603 if op_list[i] {
1604 bv += 1;
1605 }
1606 }
1607 bv
1608}
1609
1610pub fn legalize_board(board: &mut Vec<Vec<i32>>) {
1614 let row = board.len();
1615 let column = board[0].len();
1616 for x in 0..row {
1617 for y in 0..column {
1618 if board[x][y] <= -1 || board[x][y] >= 13 || board[x][y] == 9 {
1619 board[x][y] = 10;
1621 } else if board[x][y] >= 1 && board[x][y] <= 8 {
1622 let mut minenum_limit = 0;
1623 for i in max(1, x) - 1..min(row, x + 2) {
1624 for j in max(1, y) - 1..min(column, y + 2) {
1625 if board[i][j] == 10 || board[i][j] == 11 {
1626 minenum_limit += 1;
1628 }
1629 }
1630 }
1631 board[x][y] = min(board[x][y], minenum_limit);
1632 }
1633 }
1634 }
1635}
1636
1637pub fn chunk_matrixes(
1640 matrix_as: &mut Vec<Vec<Vec<i32>>>,
1641 matrix_xs: &mut Vec<Vec<(usize, usize)>>,
1642 matrix_bs: &mut Vec<Vec<i32>>,
1643) {
1644 let block_num = matrix_bs.len();
1645 let mut aas = vec![];
1646 let mut xxs = vec![];
1647 let mut bbs = vec![];
1648 for _ in 0..block_num {
1649 let aa = matrix_as.pop().unwrap();
1650 let xx = matrix_xs.pop().unwrap();
1651 let bb = matrix_bs.pop().unwrap();
1652 let (mut a_, mut x_, mut b_) = chunk_matrix(aa, xx, bb);
1653 aas.append(&mut a_);
1654 xxs.append(&mut x_);
1655 bbs.append(&mut b_);
1656 }
1657 *matrix_as = aas;
1658 *matrix_xs = xxs;
1659 *matrix_bs = bbs;
1660}
1661
1662pub fn chunk_matrix(
1665 mut matrix_a: Vec<Vec<i32>>,
1666 mut matrix_x: Vec<(usize, usize)>,
1667 mut matrix_b: Vec<i32>,
1668) -> (Vec<Vec<Vec<i32>>>, Vec<Vec<(usize, usize)>>, Vec<Vec<i32>>) {
1669 let mut block_id = 0;
1670 let mut matrix_as = vec![];
1671 let mut matrix_xs = vec![];
1672 let mut matrix_bs = vec![];
1673
1674 loop {
1675 let row_num = matrix_a.len();
1676 let column_num = matrix_a[0].len();
1677 let mut current_rows_bool = vec![false; row_num];
1678 let mut current_columns_bool = vec![false; column_num];
1679 current_columns_bool[0] = true;
1680 let mut column_buffer = vec![0];
1681 loop {
1682 let mut row_buffer = vec![];
1683 if column_buffer.is_empty() {
1684 break;
1685 }
1686 for i in &column_buffer {
1687 for idr in 0..matrix_a.len() {
1688 if matrix_a[idr][*i] >= 1 && !current_rows_bool[idr] {
1689 row_buffer.push(idr);
1690 current_rows_bool[idr] = true;
1691 }
1692 }
1693 }
1694 column_buffer.clear();
1695 if row_buffer.is_empty() {
1696 break;
1697 }
1698 for i in row_buffer {
1699 for (idc, &c) in matrix_a[i].iter().enumerate() {
1700 if c >= 1 && !current_columns_bool[idc] {
1701 column_buffer.push(idc);
1702 current_columns_bool[idc] = true;
1703 }
1704 }
1705 }
1706 }
1707 let mut current_rows = vec![];
1708 let mut current_columns = vec![];
1709 for (idx, &x) in current_columns_bool.iter().enumerate() {
1710 if x {
1711 current_columns.push(idx)
1712 }
1713 }
1714 for (idx, &x) in current_rows_bool.iter().enumerate() {
1715 if x {
1716 current_rows.push(idx)
1717 }
1718 }
1719 current_rows.sort_by(|a, b| b.cmp(a));
1720 current_rows.dedup();
1721 current_columns.sort_by(|a, b| b.cmp(a));
1722 current_columns.dedup();
1723 matrix_as.push(vec![vec![0; current_columns.len()]; current_rows.len()]);
1724 matrix_bs.push(vec![0; current_rows.len()]);
1725 matrix_xs.push(vec![(0, 0); current_columns.len()]);
1726 for (idx, x) in current_rows.iter().enumerate() {
1727 for (idy, y) in current_columns.iter().enumerate() {
1728 matrix_as[block_id][idx][idy] = matrix_a[*x][*y];
1729 }
1730 }
1731 for (idx, x) in current_rows.iter().enumerate() {
1732 matrix_bs[block_id][idx] = matrix_b[*x];
1733 }
1734 for (idy, y) in current_columns.iter().enumerate() {
1735 matrix_xs[block_id][idy] = matrix_x[*y];
1736 }
1737 for i in current_rows {
1738 matrix_a.remove(i);
1739 matrix_b.remove(i);
1740 }
1741 for j in current_columns {
1742 for k in 0..matrix_a.len() {
1743 matrix_a[k].remove(j);
1744 }
1745 matrix_x.remove(j);
1746 }
1747
1748 if matrix_b.is_empty() {
1749 break;
1750 }
1751 block_id += 1;
1752 }
1753 (matrix_as, matrix_xs, matrix_bs)
1754}
1755
1756#[test]
1757fn chunk_matrix_works() {
1758 let mut a = vec![
1759 vec![1, 1, 0, 0],
1760 vec![0, 0, 1, 1],
1761 vec![0, 1, 0, 0],
1762 vec![0, 0, 0, 1],
1763 ];
1764 let mut x = vec![(1, 2), (3, 4), (5, 6), (7, 8)];
1765 let mut b = vec![1, 2, 3, 4];
1766 let (aa, xx, bb) = chunk_matrix(a, x, b);
1767 println!("{:?}", xx);
1768}
1769
1770pub fn find_a_border_cell(
1775 board_of_game: &Vec<Vec<i32>>,
1776 xy: &(usize, usize),
1777) -> (Option<(usize, usize)>, bool) {
1778 let row = board_of_game.len();
1779 let column = board_of_game[0].len();
1780 for m in max(1, xy.0) - 1..min(row, xy.0 + 2) {
1781 for n in max(1, xy.1) - 1..min(column, xy.1 + 2) {
1782 if board_of_game[m][n] < 10 {
1783 return (Some(*xy), true);
1784 }
1785 }
1786 }
1787 let mut board_of_game_clone = board_of_game.clone();
1788 board_of_game_clone[xy.0][xy.1] = 100;
1789 let mut buffer = vec![(xy.0, xy.1)];
1790 while let Some(top) = buffer.pop() {
1791 let (i, j) = top;
1792 for m in max(1, i) - 1..min(row, i + 2) {
1793 for n in max(1, j) - 1..min(column, j + 2) {
1794 if (i != m || j != n) && board_of_game_clone[m][n] == 10 {
1795 for mm in max(1, m) - 1..min(row, m + 2) {
1796 for nn in max(1, n) - 1..min(column, n + 2) {
1797 if board_of_game_clone[mm][nn] < 10 {
1798 return (Some((m, n)), false);
1799 }
1800 }
1801 }
1802 buffer.push((m, n));
1803 board_of_game_clone[m][n] = 100;
1804 }
1805 }
1806 }
1807 }
1808 (None, false)
1809}
1810
1811pub fn is_good_chording(board_of_game: &Vec<Vec<i32>>, pos: (usize, usize)) -> bool {
1815 let row = board_of_game.len();
1816 let column = board_of_game[0].len();
1817 let mid_num = surround_cell_num(board_of_game, pos);
1818 if pos.0 > 0 {
1819 if mid_num < surround_cell_num(board_of_game, (pos.0 - 1, pos.1)) {
1820 return false;
1821 }
1822 }
1823 if pos.1 > 0 {
1824 if mid_num < surround_cell_num(board_of_game, (pos.0, pos.1 - 1)) {
1825 return false;
1826 }
1827 }
1828 if pos.0 + 1 < row {
1829 if mid_num < surround_cell_num(board_of_game, (pos.0 + 1, pos.1)) {
1830 return false;
1831 }
1832 }
1833 if pos.1 < column + 1 {
1834 if mid_num < surround_cell_num(board_of_game, (pos.0, pos.1 + 1)) {
1835 return false;
1836 }
1837 }
1838 return mid_num > 0;
1839}
1840
1841fn surround_cell_num(board_of_game: &Vec<Vec<i32>>, pos: (usize, usize)) -> i8 {
1844 let row = board_of_game.len();
1845 let column = board_of_game[0].len();
1846 if board_of_game[pos.0][pos.1] > 8 || board_of_game[pos.0][pos.1] < 1 {
1847 return -1;
1848 }
1849 let mut flag_num = 0;
1850 let mut num = 0;
1851 for m in max(1, pos.0) - 1..min(row, pos.0 + 2) {
1852 for n in max(1, pos.1) - 1..min(column, pos.1 + 2) {
1853 if board_of_game[m][n] == 10 {
1854 num += 1;
1855 } else if board_of_game[m][n] == 11 {
1856 flag_num += 1;
1857 }
1858 }
1859 }
1860 if board_of_game[pos.0][pos.1] as i8 == flag_num {
1861 return num;
1862 } else {
1863 return -1;
1864 }
1865}
1866
1867pub fn cal_board_numbers(board: &mut Vec<Vec<i32>>) {
1869 let height = board.len();
1870 let width = board[0].len();
1871 for x in 0..height {
1872 for y in 0..width {
1873 if board[x][y] == -1 {
1874 for j in max(1, x) - 1..min(height, x + 2) {
1875 for k in max(1, y) - 1..min(width, y + 2) {
1876 if board[j][k] >= 0 {
1877 board[j][k] += 1;
1878 }
1879 }
1880 }
1881 }
1882 }
1883 }
1884}