Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
* [Union Find](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/union_find.rs)
* [Veb Tree](https://github.com/TheAlgorithms/Rust/blob/master/src/data_structures/veb_tree.rs)
* Dynamic Programming
* [Catalan Numbers](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/catalan_numbers.rs)
* [Coin Change](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/coin_change.rs)
* [Egg Dropping](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/egg_dropping.rs)
* [Fibonacci](https://github.com/TheAlgorithms/Rust/blob/master/src/dynamic_programming/fibonacci.rs)
Expand Down
111 changes: 111 additions & 0 deletions src/dynamic_programming/catalan_numbers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//! Catalan Numbers using Dynamic Programming
//!
//! The Catalan numbers are a sequence of positive integers that appear in many
//! counting problems in combinatorics. Such problems include counting:
//! - The number of Dyck words of length 2n
//! - The number of well-formed expressions with n pairs of parentheses
//! (e.g., `()()` is valid but `())(` is not)
//! - The number of different ways n + 1 factors can be completely parenthesized
//! (e.g., for n = 2, C(n) = 2 and (ab)c and a(bc) are the two valid ways)
//! - The number of full binary trees with n + 1 leaves
//!
//! A Catalan number satisfies the following recurrence relation:
//! - C(0) = C(1) = 1
//! - C(n) = sum(C(i) * C(n-i-1)), from i = 0 to n-1
//!
//! Sources:
//! - [Brilliant.org](https://brilliant.org/wiki/catalan-numbers/)
//! - [Wikipedia](https://en.wikipedia.org/wiki/Catalan_number)

/// Computes the Catalan number sequence from 0 through `upper_limit`.
///
/// # Arguments
///
/// * `upper_limit` - The upper limit for the Catalan sequence (must be ≥ 0)
///
/// # Returns
///
/// A vector containing Catalan numbers from C(0) to C(upper_limit)
///
/// # Complexity
///
/// * Time complexity: O(n²)
/// * Space complexity: O(n)
///
/// where `n` is the `upper_limit`.
///
/// # Examples
///
/// ```
/// use the_algorithms_rust::dynamic_programming::catalan_numbers;
///
/// assert_eq!(catalan_numbers(5), vec![1, 1, 2, 5, 14, 42]);
/// assert_eq!(catalan_numbers(2), vec![1, 1, 2]);
/// assert_eq!(catalan_numbers(0), vec![1]);
/// ```
///
/// # Warning
///
/// This will overflow the 64-bit unsigned integer for large values of `upper_limit`.
/// For example, C(21) and beyond will cause overflow.
pub fn catalan_numbers(upper_limit: usize) -> Vec<u64> {
let mut catalan_list = vec![0u64; upper_limit + 1];

// Base case: C(0) = 1
catalan_list[0] = 1;

// Base case: C(1) = 1
if upper_limit > 0 {
catalan_list[1] = 1;
}

// Recurrence relation: C(i) = sum(C(j) * C(i-j-1)), from j = 0 to i-1
for i in 2..=upper_limit {
for j in 0..i {
catalan_list[i] += catalan_list[j] * catalan_list[i - j - 1];
}
}

catalan_list
}

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

#[test]
fn test_catalan_numbers_basic() {
assert_eq!(catalan_numbers(5), vec![1, 1, 2, 5, 14, 42]);
assert_eq!(catalan_numbers(2), vec![1, 1, 2]);
assert_eq!(catalan_numbers(0), vec![1]);
}

#[test]
fn test_catalan_numbers_single() {
assert_eq!(catalan_numbers(1), vec![1, 1]);
}

#[test]
fn test_catalan_numbers_extended() {
let result = catalan_numbers(10);
assert_eq!(result.len(), 11);
assert_eq!(result[0], 1);
assert_eq!(result[1], 1);
assert_eq!(result[2], 2);
assert_eq!(result[3], 5);
assert_eq!(result[4], 14);
assert_eq!(result[5], 42);
assert_eq!(result[6], 132);
assert_eq!(result[7], 429);
assert_eq!(result[8], 1430);
assert_eq!(result[9], 4862);
assert_eq!(result[10], 16796);
}

#[test]
fn test_catalan_first_few() {
// Verify the first few Catalan numbers match known values
assert_eq!(catalan_numbers(3), vec![1, 1, 2, 5]);
assert_eq!(catalan_numbers(4), vec![1, 1, 2, 5, 14]);
}
}
2 changes: 2 additions & 0 deletions src/dynamic_programming/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mod catalan_numbers;
mod coin_change;
mod egg_dropping;
mod fibonacci;
Expand All @@ -21,6 +22,7 @@ mod task_assignment;
mod trapped_rainwater;
mod word_break;

pub use self::catalan_numbers::catalan_numbers;
pub use self::coin_change::coin_change;
pub use self::egg_dropping::egg_drop;
pub use self::fibonacci::binary_lifting_fibonacci;
Expand Down