From 96c2b1a83db887822914ac3285165605125c905d Mon Sep 17 00:00:00 2001 From: EFanZh Date: Mon, 25 Sep 2023 21:45:12 +0800 Subject: [PATCH] Add problem 1621: Number of Sets of K Non-Overlapping Line Segments --- src/lib.rs | 1 + .../combinations.rs | 77 +++++++++++++++++++ .../mod.rs | 18 +++++ 3 files changed, 96 insertions(+) create mode 100644 src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/combinations.rs create mode 100644 src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/mod.rs diff --git a/src/lib.rs b/src/lib.rs index bd540816..9b359a7e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1333,6 +1333,7 @@ pub mod problem_1616_split_two_strings_to_make_palindrome; pub mod problem_1617_count_subtrees_with_max_distance_between_cities; pub mod problem_1619_mean_of_array_after_removing_some_elements; pub mod problem_1620_coordinate_with_maximum_network_quality; +pub mod problem_1621_number_of_sets_of_k_non_overlapping_line_segments; pub mod problem_1624_largest_substring_between_two_equal_characters; pub mod problem_1629_slowest_key; pub mod problem_1630_arithmetic_subarrays; diff --git a/src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/combinations.rs b/src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/combinations.rs new file mode 100644 index 00000000..8698e3f9 --- /dev/null +++ b/src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/combinations.rs @@ -0,0 +1,77 @@ +pub struct Solution; + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl Solution { + const MODULUS: u64 = 1_000_000_007; + + fn exp_mod(mut base: u64, mut exponent: u64) -> u64 { + let mut result = 1; + + while exponent != 0 { + if exponent & 1 != 0 { + result = (result * base) % Self::MODULUS; + } + + base = (base * base) % Self::MODULUS; + + exponent >>= 1; + } + + result + } + + // See . + fn mod_inv(x: u64) -> u64 { + Self::exp_mod(x, Self::MODULUS - 2) + } + + fn combinations(n: u64, k: u64) -> u64 { + let n_minus_k = n - k; + let (k, n_minus_k) = if n_minus_k < k { (n_minus_k, k) } else { (k, n_minus_k) }; + let mut factorial = 1; + + for i in 2..=k { + factorial = (factorial * i) % Self::MODULUS; + } + + let factorial_k = factorial; + + for i in k + 1..=n_minus_k { + factorial = (factorial * i) % Self::MODULUS; + } + + let factorial_n_minus_k = factorial; + + for i in n_minus_k + 1..=n { + factorial = (factorial * i) % Self::MODULUS; + } + + let factorial_n = factorial; + + (factorial_n * Self::mod_inv((factorial_k * factorial_n_minus_k) % Self::MODULUS)) % Self::MODULUS + } + + pub fn number_of_sets(n: i32, k: i32) -> i32 { + let n = u64::from(n as u32); + let k = u64::from(k as u32); + + Self::combinations(n + k - 1, k * 2) as _ + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::Solution for Solution { + fn number_of_sets(n: i32, k: i32) -> i32 { + Self::number_of_sets(n, k) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/mod.rs b/src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/mod.rs new file mode 100644 index 00000000..6dddb58a --- /dev/null +++ b/src/problem_1621_number_of_sets_of_k_non_overlapping_line_segments/mod.rs @@ -0,0 +1,18 @@ +pub mod combinations; + +pub trait Solution { + fn number_of_sets(n: i32, k: i32) -> i32; +} + +#[cfg(test)] +mod tests { + use super::Solution; + + pub fn run() { + let test_cases = [((4, 2), 5), ((3, 1), 3), ((30, 7), 796_297_179)]; + + for ((n, k), expected) in test_cases { + assert_eq!(S::number_of_sets(n, k), expected); + } + } +}