Skip to content

Commit

Permalink
Add problem 1895: Largest Magic Square
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Jun 8, 2024
1 parent 5aa2fcd commit 5146555
Show file tree
Hide file tree
Showing 3 changed files with 131 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 @@ -1410,6 +1410,7 @@ pub mod problem_1888_minimum_number_of_flips_to_make_the_binary_string_alternati
pub mod problem_1889_minimum_space_wasted_from_packaging;
pub mod problem_1893_check_if_all_the_integers_in_a_range_are_covered;
pub mod problem_1894_find_the_student_that_will_replace_the_chalk;
pub mod problem_1895_largest_magic_square;
pub mod problem_1897_redistribute_characters_to_make_all_strings_equal;
pub mod problem_1898_maximum_number_of_removable_characters;
pub mod problem_1899_merge_triplets_to_form_target_triplet;
Expand Down
40 changes: 40 additions & 0 deletions src/problem_1895_largest_magic_square/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
pub mod prefix_sum;

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

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

pub fn run<S: Solution>() {
let test_cases = [
(
&[[7, 1, 4, 5, 6], [2, 5, 1, 6, 4], [1, 5, 4, 3, 2], [1, 2, 7, 3, 4]] as &dyn Matrix<_>,
3,
),
(&[[5, 1, 3, 1], [9, 3, 3, 1], [1, 3, 3, 8]], 2),
(
&[
[1, 4, 6, 3, 4, 18, 14, 20],
[2, 8, 2, 19, 12, 17, 16, 17],
[11, 3, 5, 7, 8, 17, 10, 14],
[13, 9, 12, 21, 28, 5, 12, 19],
[2, 12, 7, 27, 9, 11, 18, 20],
[5, 14, 18, 8, 10, 17, 24, 26],
[15, 17, 2, 14, 16, 23, 25, 7],
[5, 3, 10, 15, 22, 29, 6, 13],
],
5,
),
(&[[8, 1, 6], [3, 5, 7], [4, 9, 2], [7, 10, 9]], 3),
(&[[1]], 1),
];

for (grid, expected) in test_cases {
assert_eq!(S::largest_magic_square(grid.to_vec()), expected);
}
}
}
90 changes: 90 additions & 0 deletions src/problem_1895_largest_magic_square/prefix_sum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
pub struct Solution;

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

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

for (y, row) in grid.iter().enumerate() {
for (x, &value) in row.iter().enumerate() {
sums[columns * y + x] = (
if x == 0 { value } else { value + sums[index - 1].0 },
if y == 0 { value } else { value + sums[index - columns].1 },
if x == 0 || y == 0 {
value
} else {
value + sums[index - (columns + 1)].2
},
if x == columns - 1 || y == 0 {
value
} else {
value + sums[index - (columns - 1)].3
},
);

index += 1;
}
}

for size in (2..=rows.min(columns)).rev() {
let mut index_start = 0;

for y in 0..=rows - size {
for x in 0..=columns - size {
let index = index_start + x;
let expected = sums[index + size - 1].0 - if x == 0 { 0 } else { sums[index - 1].0 };

if (index + columns..index + columns * size)
.step_by(columns)
.all(|i| sums[i + size - 1].0 - if x == 0 { 0 } else { sums[i - 1].0 } == expected)
&& (index..index + size).all(|i| {
sums[i + columns * (size - 1)].1
- sums.get(i.wrapping_sub(columns)).map_or(0, |sums| sums.1)
== expected
})
&& sums[index + (columns + 1) * (size - 1)].2
- if x == 0 || y == 0 {
0
} else {
sums[index - (columns + 1)].2
}
== expected
&& sums[index + columns * (size - 1)].3
- if x == columns - size || y == 0 {
0
} else {
sums[index - columns + size].3
}
== expected
{
return size as _;
}
}

index_start += columns;
}
}

1
}
}

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

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

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}

0 comments on commit 5146555

Please sign in to comment.