Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
104 changes: 104 additions & 0 deletions src/dynamic_programming/catalan_numbers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
//! 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)
///
/// # 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]);
/// ```
Comment thread
AliAlimohammadi marked this conversation as resolved.
///
/// # 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