Skip to content

Commit

Permalink
Add problem 1878: Get Biggest Three Rhombus Sums in a Grid
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jun 28, 2024
1 parent 6e38890 commit 41ee505
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1399,6 +1399,7 @@ pub mod problem_1871_jump_game_vii;
pub mod problem_1872_stone_game_viii;
pub mod problem_1876_substrings_of_size_three_with_distinct_characters;
pub mod problem_1877_minimize_maximum_pair_sum_in_array;
pub mod problem_1878_get_biggest_three_rhombus_sums_in_a_grid;
pub mod problem_1879_minimum_xor_sum_of_two_arrays;
pub mod problem_1880_check_if_word_equals_summation_of_two_words;
pub mod problem_1881_maximum_value_after_insertion;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
pub struct Solution;

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl Solution {
pub fn get_biggest_three(grid: Vec<Vec<i32>>) -> Vec<i32> {
let rows = grid.len();
let columns = grid.first().map_or(0, Vec::len);
let mut sums = vec![(0_u32, 0_u32); columns * rows].into_boxed_slice();

for (y, row) in grid.into_iter().enumerate() {
for (x, value) in row.into_iter().enumerate() {
let index = columns * y + x;
let value = value as u32;

sums[index] = (
if y == 0 || x == 0 {
value
} else {
sums[index - (columns + 1)].0 + value
},
if y == 0 || x >= columns - 1 {
value
} else {
sums[index - (columns - 1)].1 + value
},
);
}
}

let mut result = Vec::<i32>::new();

let mut add_result = |value: u32| {
if let Err(i) = result.binary_search_by(|&x| value.cmp(&(x as u32))) {
if i < 3 {
if result.len() == 3 {
result.pop();
}

result.insert(i, value as _);
}
}
};

let get_sum = |y: usize, x: usize| sums[columns * y + x];

for y in 0..rows {
for x in 0..columns {
let bottom_sum = get_sum(y, x);

add_result(bottom_sum.0 - if y == 0 || x == 0 { 0 } else { get_sum(y - 1, x - 1).0 });

let max_size = x.min(columns - 1 - x).min(y / 2);

for size in 1..=max_size {
let top = (y - size * 2, x);
let left = (y - size, x - size);
let right = (y - size, x + size);

let sum_1 = get_sum(right.0 - 1, right.1 - 1).0
- if top.0 == 0 { 0 } else { get_sum(top.0 - 1, top.1 - 1).0 };

let sum_2 = get_sum(y - 1, x + 1).1
- if right.1 >= columns - 1 {
0
} else {
get_sum(right.0 - 1, right.1 + 1).1
};

let sum_3 = bottom_sum.0 - get_sum(left.0, left.1).0;

let sum_4 = get_sum(left.0, left.1).1 - get_sum(top.0, top.1).1;

add_result(sum_1 + sum_2 + sum_3 + sum_4);
}
}
}

result
}
}

// ------------------------------------------------------ snip ------------------------------------------------------ //

impl super::Solution for Solution {
fn get_biggest_three(grid: Vec<Vec<i32>>) -> Vec<i32> {
Self::get_biggest_three(grid)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
32 changes: 32 additions & 0 deletions src/problem_1878_get_biggest_three_rhombus_sums_in_a_grid/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
pub mod iterative;

pub trait Solution {
fn get_biggest_three(grid: Vec<Vec<i32>>) -> Vec<i32>;
}

#[cfg(test)]
mod tests {
use super::Solution;
use crate::test_utilities::Matrix;

pub fn run<S: Solution>() {
let test_cases = [
(
&[
[3, 4, 5, 1, 3],
[3, 3, 4, 2, 3],
[20, 30, 200, 40, 10],
[1, 5, 5, 4, 1],
[4, 3, 2, 2, 5],
] as &dyn Matrix<_>,
&[228, 216, 211] as &[_],
),
(&[[1, 2, 3], [4, 5, 6], [7, 8, 9]], &[20, 9, 8]),
(&[[7, 7, 7]], &[7]),
];

for (grid, expected) in test_cases {
assert_eq!(S::get_biggest_three(grid.to_vec()), expected);
}
}
}

0 comments on commit 41ee505

Please sign in to comment.