44
55Catalan numbers C_n are a sequence of natural numbers that occur in
66various counting problems, often recursively defined.
7- They can be computed directly using binomial coefficients:
8- C_n = 1/( n+1) * C(2n, n)
7+ This implementation uses the dynamic programming approach based on the
8+ recursive definition: C_{ n+1} = sum_{i=0}^{n} C_i C_{n-i}
99"""
1010
1111from __future__ import annotations
@@ -32,44 +32,44 @@ def catalan_numbers(count: int) -> list[int]:
3232 ...
3333 ValueError: Count must be a non-negative integer.
3434 """
35- if not isinstance (count , int ) or count < 0 :
35+ if not isinstance (count , int ):
36+ raise ValueError ("Count must be a non-negative integer." )
37+ if count < 0 :
3638 raise ValueError ("Count must be a non-negative integer." )
3739
3840 if count == 0 :
3941 return []
4042
41- sequence : list [int ] = []
43+ # Initialize the sequence with the base case C_0 = 1
44+ sequence : list [int ] = [1 ]
45+
46+ # Dynamically compute C_n for n from 1 up to count - 1
47+ # We already have C_0, so we need 'count - 1' more elements.
48+ for n in range (1 , count ):
49+ c_n = 0
50+ # The recursive formula is C_n = sum_{i=0}^{n-1} C_i * C_{n-1-i}
51+ # C_n is the sum of products of previously computed Catalan numbers.
52+ # sequence currently holds [C_0, C_1, ..., C_{n-1}]
53+ # The length of 'sequence' is 'n'
54+ for i in range (n ):
55+ # C_i * C_{n-1-i}
56+ c_n += sequence [i ] * sequence [n - 1 - i ]
4257
43- for n in range (count ):
44- # Calculate C_n using the formula: C_n = (1 / (n + 1)) * (2n choose n)
45- # Using math.comb for direct, efficient calculation of binomial coefficient
46- # math.comb(N, K) computes N! / (K! * (N - K)!)
47- try :
48- binomial_coeff = math .comb (2 * n , n )
49- c_n = binomial_coeff // (n + 1 )
50- sequence .append (c_n )
51- except AttributeError :
52- # Fallback for older Python versions (< 3.8) without math.comb
53- # This uses the factorial-based formula: (2n)! / ((n+1)! n!)
54- if n == 0 :
55- sequence .append (1 )
56- else :
57- numerator = math .factorial (2 * n )
58- denominator = math .factorial (n + 1 ) * math .factorial (n )
59- sequence .append (numerator // denominator )
58+ sequence .append (c_n )
6059
6160 return sequence
6261
6362
6463if __name__ == "__main__" :
65- import math
6664 import doctest
65+
6766 doctest .testmod ()
67+
6868 try :
6969 num = int (input ("Enter the number of Catalan numbers to generate: " ))
7070 if num < 0 :
7171 print ("Please enter a non-negative integer." )
7272 else :
7373 print (f"The first { num } Catalan numbers are: { catalan_numbers (num )} " )
7474 except ValueError :
75- print ("Invalid input. Please enter an integer." )
75+ print ("Invalid input. Please enter an integer." )
0 commit comments