Reputation:
I have a task to find number of expressions containing n parentheses which are correctly matched. So, I decided to use Catalan number. Here is a python code.
from decimal import Decimal
n = int(input())
res = Decimal(1)
k = n//2
for i in range(1, k+1):
res = Decimal(res*(n-k+i)/i)
res = int(res)
print(int(res//(k+1)))
After testing it in testing system, I have only 2 correct answers of 100. When: n = 2
(answer: 1) ans n = 4
(answer: 2). I can't look at other testing examples. Can you, please, help me? Where am I wrong?
Upvotes: 0
Views: 302
Reputation: 42133
Since the value of C(2n,n) is always going to be an integer and can be computed with only integer intermediate results, you can use integer arithmetics without any risk of running into number representation issues:
def catalan(n):
c = 1
for p in range(n+1,2*n+1):
c = c * p // (p-n)
return c // (n+1)
for n in range(10): print(catalan(n))
1
1
2
5
14
42
132
429
1430
4862
This is based on the definition of Catalan numbers found here: https://en.wikipedia.org/wiki/Catalan_number
Python 3.8 now has a combination function in the math module which would make this even easier:
def catalan(n): return math.comb(2*n,n)//(n+1)
For prior versions of Python, you could make your own comb() function:
def comb(n,r):
if n-r > r: return comb(n,n-r)
result = 1
for i in range(r+1,n+1):
result = result * i // (i-r)
return result
Note that the first catalan function above uses a streamlined version of this
Upvotes: 1
Reputation: 149085
You are probably trying to use Decimal numbers because your know that floating point arithmetic is broken. Unfortunately Decimal arithmetic is broken too and for the same underlying reason: rational numbers can only be exactly represented if the denominator of the reduced fraction only contains factors dividing 10
in that numeration system.
In base 2 (common floating point) only 1/2**n fractions can be represented, so 0.2
(1/5) can only be represented as an approximation. But in base 10, 0.1
can indeed be represented but 1/3 is the infinite 0.33333... that will be an approximation in a finite computer.
As you use rational numbers that by construction will finally give integer values, you have two possible paths:
fractions.Fraction
: a Fraction keeps separatedly its numerator and denominator parts. So all rational arithmetics give an exact representation (as a Fraction but neither as a floating point or Decimal)TL/DR: just replace Decimal with Fraction if you want exact rational arithmetics
But you formule looks weird. According to Wikipedia, it should be Prod(n-k/k) for 2<=k<=n
:
from fractions import Fraction
n = int(input())
res = 1
for k in range(2, n+1):
res = res * Fraction(n-k, k)
res = int(res)
print(int(res//(k+1)))
I can confirm that this formula gives the first 10 Catalan numbers.
Upvotes: 0
Reputation: 54733
I'm not sure where you got your Catalan formula, nor why you think this is related to finding parentheses, nor why you used the Decimal type at all. The following program prints the Nth Catalan number:
n = int(input())
res = 1
for k in range(2,n+1):
res = res * (n+k) / k
print( int(res) )
Upvotes: 0