From e4e47d715f8a6d9c259f152126b43de48b19d32a Mon Sep 17 00:00:00 2001 From: EFanZh Date: Thu, 14 Nov 2024 21:33:58 +0800 Subject: [PATCH] Add problem 2320: Count Number of Ways to Place Houses --- src/lib.rs | 1 + .../matrix_multiplication.rs | 59 +++++++++++++++++++ .../mod.rs | 18 ++++++ 3 files changed, 78 insertions(+) create mode 100644 src/problem_2320_count_number_of_ways_to_place_houses/matrix_multiplication.rs create mode 100644 src/problem_2320_count_number_of_ways_to_place_houses/mod.rs diff --git a/src/lib.rs b/src/lib.rs index bea04a14..99868a21 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1722,6 +1722,7 @@ pub mod problem_2315_count_asterisks; pub mod problem_2316_count_unreachable_pairs_of_nodes_in_an_undirected_graph; pub mod problem_2317_maximum_xor_after_operations; pub mod problem_2319_check_if_matrix_is_x_matrix; +pub mod problem_2320_count_number_of_ways_to_place_houses; #[cfg(test)] mod test_utilities; diff --git a/src/problem_2320_count_number_of_ways_to_place_houses/matrix_multiplication.rs b/src/problem_2320_count_number_of_ways_to_place_houses/matrix_multiplication.rs new file mode 100644 index 00000000..260c1edd --- /dev/null +++ b/src/problem_2320_count_number_of_ways_to_place_houses/matrix_multiplication.rs @@ -0,0 +1,59 @@ +pub struct Solution; + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +type Matrix = (u64, u64); + +impl Solution { + const MODULUS: u64 = 1_000_000_007; + + fn matrix_multiply(lhs: Matrix, rhs: Matrix) -> Matrix { + ( + (lhs.0 * (rhs.0 + rhs.1) + lhs.1 * rhs.0) % Self::MODULUS, + (lhs.0 * rhs.0 + lhs.1 * rhs.1) % Self::MODULUS, + ) + } + + fn exp_mod(mut exponent: u32) -> Matrix { + let mut base = (1, 0); + let mut result = (0, 1); + + loop { + if exponent & 1 != 0 { + result = Self::matrix_multiply(result, base); + } + + exponent >>= 1; + + if exponent == 0 { + break; + } + + base = Self::matrix_multiply(base, base); + } + + result + } + + pub fn count_house_placements(n: i32) -> i32 { + let matrix = Self::exp_mod(n as _); + + ((matrix.0 * 2 + matrix.1).pow(2) % Self::MODULUS) as _ + } +} + +// ------------------------------------------------------ snip ------------------------------------------------------ // + +impl super::Solution for Solution { + fn count_house_placements(n: i32) -> i32 { + Self::count_house_placements(n) + } +} + +#[cfg(test)] +mod tests { + #[test] + fn test_solution() { + super::super::tests::run::(); + } +} diff --git a/src/problem_2320_count_number_of_ways_to_place_houses/mod.rs b/src/problem_2320_count_number_of_ways_to_place_houses/mod.rs new file mode 100644 index 00000000..0c3f35d0 --- /dev/null +++ b/src/problem_2320_count_number_of_ways_to_place_houses/mod.rs @@ -0,0 +1,18 @@ +pub mod matrix_multiplication; + +pub trait Solution { + fn count_house_placements(n: i32) -> i32; +} + +#[cfg(test)] +mod tests { + use super::Solution; + + pub fn run() { + let test_cases = [(0, 1), (1, 4), (2, 9), (3, 25), (4, 64), (5, 169), (1000, 500_478_595)]; + + for (n, expected) in test_cases { + assert_eq!(S::count_house_placements(n), expected); + } + } +}