Skip to content

Commit 01aa8ab

Browse files
committed
Added Valid Sudoku
1 parent e77c6ea commit 01aa8ab

File tree

1 file changed

+117
-8
lines changed

1 file changed

+117
-8
lines changed

src/valid_sudoku.rs

+117-8
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,135 @@
1-
/// TODO: Fill In
1+
/// Determine if a `9 x 9` Sudoku board is valid. Only the filled cells need to
2+
/// be validated according to the following rules:
3+
///
4+
/// Each row must contain the digits `1-9` without repetition.
5+
///
6+
/// Each column must contain the digits `1-9` without repetition.
7+
///
8+
/// Each of the nine `3 x 3` sub-boxes of the grid must contain the digits `1-9`
9+
/// without repetition.
10+
///
11+
/// Note:
12+
/// * A Sudoku board (partially filled) could be valid but is not necessarily
13+
/// solvable.
14+
///
15+
/// * Only the filled cells need to be validated according to the mentioned
16+
/// rules.
217
struct Solution;
318

419
impl Solution {
5-
// TODO: Implement
6-
pub fn is_valid_sudoku(_board: Vec<Vec<char>>) -> bool {
7-
false
20+
21+
fn char_to_index(c: char) -> usize {
22+
c.to_digit(10).unwrap_or_default() as usize
23+
}
24+
25+
fn is_valid_component<F>(board: &Vec<Vec<char>>, f: F) -> bool
26+
where F: Fn(&Vec<Vec<char>>, usize) -> char {
27+
28+
let mut result = true;
29+
let mut working = vec![0; 10];
30+
for i in 0..9 {
31+
let value = f(board, i);
32+
if value != '.' {
33+
let w = Self::char_to_index(value);
34+
if working[w] == w {
35+
result = false;
36+
break;
37+
} else { working[w] = w; }
38+
}
39+
}
40+
41+
result
42+
}
43+
44+
fn is_valid_section(board: &Vec<Vec<char>>, sec: usize) -> bool {
45+
let row_offset = match sec {
46+
0 | 1 | 2 => 0,
47+
3 | 4 | 5 => 3,
48+
6 | 7 | 8 => 6,
49+
_ => 0,
50+
};
51+
let col_offset = match sec {
52+
0 | 3 | 6 => 0,
53+
1 | 4 | 7 => 3,
54+
2 | 5 | 8 => 6,
55+
_ => 0,
56+
};
57+
58+
Self::is_valid_component(board, |board, num| {
59+
let (row, col) = match num {
60+
0 => (0 + row_offset, 0 + col_offset),
61+
1 => (0 + row_offset, 1 + col_offset),
62+
2 => (0 + row_offset, 2 + col_offset),
63+
3 => (1 + row_offset, 0 + col_offset),
64+
4 => (1 + row_offset, 1 + col_offset),
65+
5 => (1 + row_offset, 2 + col_offset),
66+
6 => (2 + row_offset, 0 + col_offset),
67+
7 => (2 + row_offset, 1 + col_offset),
68+
8 => (2 + row_offset, 2 + col_offset),
69+
_ => (0, 0)
70+
};
71+
board[row][col]
72+
})
73+
}
74+
75+
fn is_valid_column(board: &Vec<Vec<char>>, col: usize) -> bool {
76+
Self::is_valid_component(board, |board, row| board[row][col])
77+
}
78+
79+
fn is_valid_row(board: &Vec<Vec<char>>, row: usize) -> bool {
80+
Self::is_valid_component(board, |board, col| board[row][col])
881
}
82+
83+
pub fn is_valid_sudoku(board: Vec<Vec<char>>) -> bool {
84+
let mut result = true;
85+
86+
for i in 0..9 {
87+
result = result && Self::is_valid_row(&board, i);
88+
result = result && Self::is_valid_column(&board, i);
89+
result = result && Self::is_valid_section(&board, i);
90+
}
91+
92+
result
93+
}
94+
995
}
1096

1197
#[cfg(test)]
1298
mod tests {
1399
use super::Solution;
14100

15-
#[ignore]
16101
#[test]
17102
fn example_1() {
18-
// TODO: Fill In
103+
let board = vec![
104+
vec!['5','3','.','.','7','.','.','.','.'],
105+
vec!['6','.','.','1','9','5','.','.','.'],
106+
vec!['.','9','8','.','.','.','.','6','.'],
107+
vec!['8','.','.','.','6','.','.','.','3'],
108+
vec!['4','.','.','8','.','3','.','.','1'],
109+
vec!['7','.','.','.','2','.','.','.','6'],
110+
vec!['.','6','.','.','.','.','2','8','.'],
111+
vec!['.','.','.','4','1','9','.','.','5'],
112+
vec!['.','.','.','.','8','.','.','7','9']
113+
];
114+
let result = Solution::is_valid_sudoku(board);
115+
assert!(result);
19116
}
20117

21-
#[ignore]
22118
#[test]
23119
fn example_2() {
24-
// TODO: Fill In
120+
let board = vec![
121+
vec!['8','3','.','.','7','.','.','.','.'],
122+
vec!['6','.','.','1','9','5','.','.','.'],
123+
vec!['.','9','8','.','.','.','.','6','.'],
124+
vec!['8','.','.','.','6','.','.','.','3'],
125+
vec!['4','.','.','8','.','3','.','.','1'],
126+
vec!['7','.','.','.','2','.','.','.','6'],
127+
vec!['.','6','.','.','.','.','2','8','.'],
128+
vec!['.','.','.','4','1','9','.','.','5'],
129+
vec!['.','.','.','.','8','.','.','7','9']
130+
];
131+
let result = Solution::is_valid_sudoku(board);
132+
assert!(!result);
25133
}
134+
26135
}

0 commit comments

Comments
 (0)