use std::collections::{HashSet, VecDeque}; type Position = (i32, i32); type Grid = Vec>; impl Solution { fn indices(grid: &Grid) -> impl Iterator + '_ { (0..grid.len() as i32) .flat_map(move |y| (0..grid[y as usize].len() as i32).map(move |x| (y, x))) } fn interesting(grid: &Grid, visited: &HashSet, p: &Position) -> bool { let (max_y, max_x) = (grid.len() as i32, grid[0].len() as i32); let &(y, x) = p; y >= 0 && y < max_y && x >= 0 && x < max_x && grid[p.0 as usize][p.1 as usize] != '0' && !visited.contains(p) } fn bfs(grid: &Grid, visited: &mut HashSet, pos: Position) { let mut queue: VecDeque = VecDeque::new(); queue.push_back(pos); visited.insert(pos); while let Some(p) = queue.pop_front() { for d in [-1, 1] { for adjacent in [(p.0 + d, p.1), (p.0, p.1 + d)] { if Solution::interesting(grid, visited, &adjacent) { queue.push_back(adjacent); visited.insert(adjacent); } } } } } pub fn num_islands(grid: Grid) -> i32 { let mut visited: HashSet = HashSet::new(); let mut islands = 0; for (y, x) in Solution::indices(&grid) { if !Solution::interesting(&grid, &visited, &(y, x)) { continue; } Solution::bfs(&grid, &mut visited, (y, x)); islands += 1; } islands } } struct Solution {} fn main() { println!("Hello World!"); } #[cfg(test)] mod tests { use super::*; #[test] fn test_example_1() { assert_eq!( Solution::num_islands(vec![ vec!['1', '1', '1', '1', '0'], vec!['1', '1', '0', '1', '0'], vec!['1', '1', '0', '0', '0'], vec!['0', '0', '0', '0', '0'] ]), 1 ); } #[test] fn test_example_2() { assert_eq!( Solution::num_islands(vec![ vec!['1', '1', '0', '0', '0'], vec!['1', '1', '0', '0', '0'], vec!['0', '0', '1', '0', '0'], vec!['0', '0', '0', '1', '1'] ]), 3 ); } }