Skip to content

Commit

Permalink
Add problem 1621: Number of Sets of K Non-Overlapping Line Segments
Browse files Browse the repository at this point in the history
  • Loading branch information
EFanZh committed Sep 25, 2023
1 parent 53b298c commit 96c2b1a
Show file tree
Hide file tree
Showing 3 changed files with 96 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 @@ -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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <https://en.wikipedia.org/wiki/Modular_multiplicative_inverse#Using_Euler's_theorem>.
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::<super::Solution>();
}
}
Original file line number Diff line number Diff line change
@@ -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<S: Solution>() {
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);
}
}
}

0 comments on commit 96c2b1a

Please sign in to comment.