diff --git a/rs/find-all-groups-of-farmland.rs b/rs/find-all-groups-of-farmland.rs new file mode 100644 index 0000000..ea6a77d --- /dev/null +++ b/rs/find-all-groups-of-farmland.rs @@ -0,0 +1,51 @@ +struct Solution {} +impl Solution { + fn dimensions(grid: &[Vec]) -> (usize, usize) { + (grid.len(), grid[0].len()) + } + + fn indices(m: usize, n: usize) -> impl Iterator { + (0..m).flat_map(move |y| (0..n).map(move |x| (x, y))) + } + + fn find(land: &[Vec], visited: &mut [Vec], min_x: usize, min_y: usize) -> Vec { + // horizontally + let mut max_x = min_x; + while max_x < land[min_y].len() && land[min_y][max_x] == 1 { + max_y += 1; + } + + // vertically + let mut max_y = min_y; + while max_y < land.len() && land[max_y][min_x] == 1 { + max_y += 1; + } + + // mark all as visited + for (x, y) in (min_y..max_y).flat_map(move |y| (min_x..max_x).map(move |x| (x, y))) { + visited[y][x] = true; + } + + vec![min_y, min_x, max_y - 1, max_x - 1] + .into_iter() + .map(|c| c as i32) + .collect() + } + + pub fn find_farmland(land: Vec>) -> Vec> { + let (m, n) = Self::dimensions(&land); + + let mut farmland: Vec> = Vec::new(); + + let mut visited = vec![vec![false; n]; m]; + for (x, y) in Self::indices(m, n) { + if land[y][x] == 0 || visited[y][x] { + continue; + } + + farmland.push(Self::find(&land, &mut visited, x, y)); + } + + farmland + } +}