1+ # Catalan Numbers Implementation in R
2+ #
3+ # Catalan numbers form a sequence of natural numbers that occur in various counting problems.
4+ # The nth Catalan number is given by the formula: C(n) = (2n)! / ((n+1)! * n!)
5+ # They appear in problems like counting binary trees, valid parentheses combinations,
6+ # paths in a grid, and polygon triangulations.
7+ #
8+ # Time Complexity: O(n) for iterative approach, O(n^2) for recursive with memoization
9+ # Space Complexity: O(n) for memoization table
10+
11+ # Function to calculate nth Catalan number using dynamic programming
12+ # @param n: Non-negative integer for which to calculate Catalan number
13+ # @return: The nth Catalan number
14+ catalan_dp <- function (n ) {
15+ # Base cases
16+ if (n < = 1 ) {
17+ return (1 )
18+ }
19+
20+ # Initialize dp table
21+ catalan <- numeric (n + 1 )
22+ catalan [1 ] <- 1 # C(0) = 1
23+ catalan [2 ] <- 1 # C(1) = 1
24+
25+ # Fill the table using the recurrence relation:
26+ # C(n) = sum(C(i) * C(n-1-i)) for i from 0 to n-1
27+ for (i in 2 : n ) {
28+ catalan [i + 1 ] <- 0
29+ for (j in 0 : (i - 1 )) {
30+ catalan [i + 1 ] <- catalan [i + 1 ] + catalan [j + 1 ] * catalan [i - j ]
31+ }
32+ }
33+
34+ return (catalan [n + 1 ])
35+ }
36+
37+ # Function to calculate nth Catalan number using direct formula
38+ # @param n: Non-negative integer for which to calculate Catalan number
39+ # @return: The nth Catalan number
40+ catalan_formula <- function (n ) {
41+ if (n < = 1 ) {
42+ return (1 )
43+ }
44+
45+ # Use the formula: C(n) = (2n)! / ((n+1)! * n!)
46+ # Simplified to: C(n) = (2n choose n) / (n+1)
47+ result <- 1
48+
49+ # Calculate using the iterative formula to avoid large factorials
50+ for (i in 0 : (n - 1 )) {
51+ result <- result * (n + i + 1 ) / (i + 1 )
52+ }
53+
54+ return (result / (n + 1 ))
55+ }
56+
57+ # Function to generate first n Catalan numbers
58+ # @param n: Number of Catalan numbers to generate
59+ # @return: Vector containing first n Catalan numbers
60+ first_n_catalan <- function (n ) {
61+ if (n < = 0 ) {
62+ return (numeric (0 ))
63+ }
64+
65+ result <- numeric (n )
66+
67+ for (i in 1 : n ) {
68+ result [i ] <- catalan_dp(i - 1 ) # Generate C(0) to C(n-1)
69+ }
70+
71+ return (result )
72+ }
73+
74+ # Function to find applications of Catalan numbers
75+ # @param n: The index for which to show applications
76+ # @return: List of interpretations of the nth Catalan number
77+ catalan_applications <- function (n ) {
78+ cat_n <- catalan_dp(n )
79+
80+ applications <- list (
81+ value = cat_n ,
82+ interpretations = c(
83+ paste(" Number of ways to arrange" , n , " pairs of parentheses" ),
84+ paste(" Number of full binary trees with" , n + 1 , " leaves" ),
85+ paste(" Number of ways to triangulate a convex polygon with" , n + 2 , " vertices" ),
86+ paste(" Number of monotonic lattice paths from (0,0) to (n,n) not crossing y=x" ),
87+ paste(" Number of ways to arrange" , n , " non-attacking rooks on a triangular board" )
88+ )
89+ )
90+
91+ return (applications )
92+ }
93+
94+ # Example usage:
95+ # # Calculate specific Catalan numbers
96+ # print(paste("5th Catalan number (DP):", catalan_dp(5)))
97+ # print(paste("5th Catalan number (Formula):", catalan_formula(5)))
98+ #
99+ # # Generate first 10 Catalan numbers
100+ # first_10 <- first_n_catalan(10)
101+ # print("First 10 Catalan numbers:")
102+ # print(first_10)
103+ #
104+ # # Show applications of 4th Catalan number
105+ # apps <- catalan_applications(4)
106+ # print(paste("C(4) =", apps$value))
107+ # print("Applications:")
108+ # for (app in apps$interpretations) {
109+ # print(app)
110+ # }
0 commit comments