@@ -5,6 +5,8 @@ use crate::util::Array2D;
5
5
6
6
pub type DefaultBoard = SudokuBoard < 9 , 3 > ;
7
7
8
+ /// Struct that keeps track of the numbers in the board and also what values are already used
9
+ /// in each row/column/block
8
10
#[ derive( Clone , Eq , PartialEq ) ]
9
11
pub struct SudokuBoard < const SIZE : usize , const BLOCK_SIZE : usize > {
10
12
pub numbers : Array2D < Option < u8 > , SIZE > ,
@@ -31,16 +33,14 @@ impl<const SIZE: usize, const BLOCK_SIZE: usize> SudokuBoard<SIZE, BLOCK_SIZE> {
31
33
32
34
pub fn set_number ( & mut self , value : Option < u8 > , row : usize , col : usize ) {
33
35
let prev = self . numbers [ row] [ col] ;
34
- if prev. is_some ( ) {
35
- let val = prev. unwrap ( ) ;
36
+ if let Some ( val) = prev {
36
37
self . rows [ row] . remove_number ( val) ;
37
38
self . cols [ col] . remove_number ( val) ;
38
39
self . blocks [ row / BLOCK_SIZE ] [ col / BLOCK_SIZE ] . remove_number ( val) ;
39
40
self . numbers [ row] [ col] = None ;
40
41
}
41
42
42
- if value. is_some ( ) {
43
- let val = value. unwrap ( ) ;
43
+ if let Some ( val) = value {
44
44
self . rows [ row] . add_number ( val) ;
45
45
self . cols [ col] . add_number ( val) ;
46
46
self . blocks [ row / BLOCK_SIZE ] [ col / BLOCK_SIZE ] . add_number ( val) ;
@@ -60,9 +60,9 @@ impl<const SIZE: usize, const BLOCK_SIZE: usize> SudokuBoard<SIZE, BLOCK_SIZE> {
60
60
let mut board = SudokuBoard :: new ( ) ;
61
61
62
62
literal
63
- . replace ( '\n' , & " " )
64
- . split ( " " )
65
- . filter ( |o| o . len ( ) != 0 )
63
+ . replace ( '\n' , " " )
64
+ . split ( ' ' )
65
+ . filter ( |o| !o . is_empty ( ) )
66
66
. enumerate ( )
67
67
. for_each ( |( index, o) | {
68
68
board. set_number ( u8:: from_str ( o) . ok ( ) , index / SIZE , index % SIZE )
@@ -71,6 +71,8 @@ impl<const SIZE: usize, const BLOCK_SIZE: usize> SudokuBoard<SIZE, BLOCK_SIZE> {
71
71
board
72
72
}
73
73
74
+ /// Return a more compact representation of the board, in the format "1 2 3 _ _ 6 7 8 _"
75
+ /// without newlines
74
76
pub fn to_literal ( & self ) -> String {
75
77
let mut result = String :: new ( ) ;
76
78
for row in & self . numbers {
@@ -91,10 +93,10 @@ impl<const SIZE: usize, const BLOCK_SIZE: usize> SudokuBoard<SIZE, BLOCK_SIZE> {
91
93
let mut board = SudokuBoard :: new ( ) ;
92
94
93
95
for ( index, number) in literal
94
- . replace ( '\n' , & " " )
95
- . split ( " " )
96
- . filter ( |o| o . len ( ) != 0 )
97
- . map ( |o| u8:: from_str ( o ) )
96
+ . replace ( '\n' , " " )
97
+ . split ( ' ' )
98
+ . filter ( |o| !o . is_empty ( ) )
99
+ . map ( u8:: from_str)
98
100
. enumerate ( )
99
101
. filter ( |( _, o) | o. is_ok ( ) )
100
102
. map ( |( index, o) | ( index, o. unwrap ( ) ) ) {
@@ -132,14 +134,19 @@ impl<const SIZE: usize, const BLOCK_SIZE: usize> SudokuBoard<SIZE, BLOCK_SIZE> {
132
134
true
133
135
}
134
136
137
+ /// Returns a readable representation of the board
135
138
pub fn board_to_string ( & self ) -> String {
136
139
let mut result = String :: new ( ) ;
137
140
result += " ---------------------\n " ;
138
141
139
142
for row in 0 ..SIZE {
140
143
result += & format ! ( "{} | " , row) ;
141
144
for col in 0 ..SIZE {
142
- result += & ( self . numbers [ row] [ col] . map ( |x| x. to_string ( ) ) . unwrap_or ( "_" . to_owned ( ) ) . to_string ( ) + " " ) ;
145
+ match self . numbers [ row] [ col] {
146
+ Some ( x) => result += & x. to_string ( ) ,
147
+ None => result += "_" ,
148
+ }
149
+ result += " " ;
143
150
}
144
151
result += "|\n " ;
145
152
}
@@ -160,11 +167,6 @@ impl<const SIZE: usize, const BLOCK_SIZE: usize> Debug for SudokuBoard<SIZE, BLO
160
167
mod tests {
161
168
use crate :: sudoku_board:: { DefaultBoard } ;
162
169
163
- #[ test]
164
- fn util ( ) {
165
- assert ! ( true ) ;
166
- }
167
-
168
170
#[ test]
169
171
fn empty_board ( ) {
170
172
let board = DefaultBoard :: new ( ) ;
0 commit comments