Skip to content

Commit

Permalink
Add problem 1775: Equal Sum Arrays With Minimum Number of Operations
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Sep 29, 2023
1 parent 72deb05 commit ce30974
Show file tree
Hide file tree
Showing 3 changed files with 109 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 @@ -1398,6 +1398,7 @@ pub mod problem_1765_map_of_highest_peak;
pub mod problem_1768_merge_strings_alternately;
pub mod problem_1769_minimum_number_of_operations_to_move_all_balls_to_each_box;
pub mod problem_1773_count_items_matching_a_rule;
pub mod problem_1775_equal_sum_arrays_with_minimum_number_of_operations;
pub mod problem_1779_find_nearest_point_that_has_the_same_x_or_y_coordinate;
pub mod problem_1780_check_if_number_is_a_sum_of_powers_of_three;
pub mod problem_1781_sum_of_beauty_of_all_substrings;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
pub struct Solution;

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

use std::mem;

impl Solution {
fn count_nums(nums: Vec<i32>) -> [u32; 6] {
let mut result = [0; 6];

for num in nums {
result[num as u32 as usize - 1] += 1;
}

result
}

fn calculate_sum(counts: &[u32; 6]) -> u32 {
let mut result = 0;
let mut i = 0;

for count in counts {
i += 1;
result += i * count;
}

result
}

pub fn min_operations(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
let mut counts_1 = Self::count_nums(nums1);
let sums_1 = Self::calculate_sum(&counts_1);
let mut counts_2 = Self::count_nums(nums2);
let sums_2 = Self::calculate_sum(&counts_2);

let mut diff = if sums_2 < sums_1 {
mem::swap(&mut counts_1, &mut counts_2);

sums_1 - sums_2
} else {
sums_2 - sums_1
};

let mut iter = counts_1.iter().zip(counts_2.iter().rev()).map(|(lhs, rhs)| lhs + rhs);
let mut gain = 6;
let mut result = 0;

while diff != 0 {
if let Some(count) = iter.next() {
gain -= 1;

if let Some(required) = (diff + gain - 1).checked_div(gain) {
if count < required {
result += count;

diff -= gain * count;
} else {
result += required;

break;
}
}
} else {
return -1;
}
}

result as _
}
}

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

impl super::Solution for Solution {
fn min_operations(nums1: Vec<i32>, nums2: Vec<i32>) -> i32 {
Self::min_operations(nums1, nums2)
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_solution() {
super::super::tests::run::<super::Solution>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
pub mod greedy;

pub trait Solution {
fn min_operations(nums1: Vec<i32>, nums2: Vec<i32>) -> i32;
}

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

pub fn run<S: Solution>() {
let test_cases = [
((&[1, 2, 3, 4, 5, 6] as &[_], &[1, 1, 2, 2, 2, 2] as &[_]), 3),
((&[1, 1, 1, 1, 1, 1, 1], &[6]), -1),
((&[6, 6], &[1]), 3),
];

for ((nums1, nums2), expected) in test_cases {
assert_eq!(S::min_operations(nums1.to_vec(), nums2.to_vec()), expected);
}
}
}

0 comments on commit ce30974

Please sign in to comment.