From e7959dcf7d48a1e41509f9ab9d34eb80d9dc341d Mon Sep 17 00:00:00 2001 From: Denis Daletski Date: Fri, 28 Apr 2023 22:08:45 -0400 Subject: [PATCH] largest-plus-sign --- rust/Cargo.lock | 8 ++ rust/problems/largest-plus-sign/Cargo.toml | 12 +++ rust/problems/largest-plus-sign/link.txt | 1 + rust/problems/largest-plus-sign/src/lib.rs | 108 +++++++++++++++++++++ 4 files changed, 129 insertions(+) create mode 100644 rust/problems/largest-plus-sign/Cargo.toml create mode 100644 rust/problems/largest-plus-sign/link.txt create mode 100644 rust/problems/largest-plus-sign/src/lib.rs diff --git a/rust/Cargo.lock b/rust/Cargo.lock index a101886..3e064b9 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -546,6 +546,14 @@ dependencies = [ "spectral", ] +[[package]] +name = "largest-plus-sign" +version = "0.1.0" +dependencies = [ + "common", + "rstest 0.16.0", +] + [[package]] name = "lazy_static" version = "1.4.0" diff --git a/rust/problems/largest-plus-sign/Cargo.toml b/rust/problems/largest-plus-sign/Cargo.toml new file mode 100644 index 0000000..ef7257c --- /dev/null +++ b/rust/problems/largest-plus-sign/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "largest-plus-sign" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] + +[dev-dependencies] +common = { path = "../../common" } +rstest = "0.16.0" diff --git a/rust/problems/largest-plus-sign/link.txt b/rust/problems/largest-plus-sign/link.txt new file mode 100644 index 0000000..6cc2184 --- /dev/null +++ b/rust/problems/largest-plus-sign/link.txt @@ -0,0 +1 @@ +https://leetcode.com/problems/largest-plus-sign \ No newline at end of file diff --git a/rust/problems/largest-plus-sign/src/lib.rs b/rust/problems/largest-plus-sign/src/lib.rs new file mode 100644 index 0000000..673a9fb --- /dev/null +++ b/rust/problems/largest-plus-sign/src/lib.rs @@ -0,0 +1,108 @@ +pub struct Solution {} + +impl Solution { + pub fn fill_mines_grid(n: usize, mines: Vec>) -> Vec { + let mut mines_grid: Vec = vec![]; + mines_grid.resize((n * n) as usize, false); + for mine in mines { + mines_grid[(mine[0] * n as i32 + mine[1]) as usize] = true; + } + mines_grid + } + + pub fn fill_orders_grid(n: usize) -> Vec { + let mut orders_grid: Vec = vec![]; + orders_grid.resize(n * n, n as i32); + orders_grid + } + + pub fn order_of_largest_plus_sign(n: i32, mines: Vec>) -> i32 { + let n = n as usize; + let mines_grid = Solution::fill_mines_grid(n, mines); + let mut orders_grid = Solution::fill_orders_grid(n); + + // for each line: + // - find segments containing only 1s + // - use segment endpoints to filter possible orders of all crosses with centers inside the segment + for y in 0..n { + let mut start = 0; + while start < n { + // find segment containing only 1s + while start < n && mines_grid[y * n + start] { + orders_grid[y * n + start] = 0; + start += 1; + } + if start == n { + break; + } + let mut end = start + 1; + while end < n && !mines_grid[(y * n + end) as usize] { + end += 1; + } + + for x in start..(start + end) / 2 { + let order = &mut orders_grid[(y * n + x) as usize]; + *order = (*order).min((x - start + 1) as i32); + } + + for x in (start + end) / 2..end { + let order = &mut orders_grid[(y * n + x) as usize]; + *order = (*order).min((end - x) as i32); + } + + start = end; + } + } + + // the same for vertical lines + for x in 0..n { + let mut start = 0; + while start < n { + while start < n && mines_grid[(start * n + x) as usize] { + start += 1; + } + if start == n { + break; + } + let mut end = start + 1; + while end < n && !mines_grid[(end * n + x) as usize] { + end += 1; + } + + for y in start..(start + end) / 2 { + let order = &mut orders_grid[(y * n + x) as usize]; + *order = (*order).min((y - start + 1) as i32); + } + + for y in (start + end) / 2..end { + let order = &mut orders_grid[(y * n + x) as usize]; + *order = (*order).min((end - y) as i32); + } + + start = end; + } + } + + orders_grid.iter().max().unwrap().clone() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use common::{assert_returns, vec2d}; + use rstest::rstest; + + #[rstest] + #[case(5, vec2d![[4,2]], 2)] + #[case(1, vec2d![[0,0]], 0)] + #[case(5, vec2d![[0,1],[0,2],[1,0],[1,2],[1,4],[2,0],[2,2],[3,0],[3,1],[4,0],[4,1],[4,3],[4,4]], 1)] + fn it_works(#[case] n: i32, #[case] mines: Vec>, #[case] expected: i32) { + assert_returns!( + expected, + Solution::order_of_largest_plus_sign, + n, + mines.clone() + ); + } +}