Catalan numbers appear in several areas of mathematics. For example, the nth Catalan number is the number of planar binary trees with n nodes, and is the number of ways of cutting up a polygon with n+2 sides into triangles by drawing non-intersecting diagonals.
Catalan numbers 0-8 are: 1 1 2 5 14 42 132 429 1430
The question we will look at here is how to calculate the nth Catalan number, for n taking values of 5, 10, 1000, 10000 and up.
In [ ]:
n=: 5
In [ ]:
(!2*n) % (!n) * (!n+1)
In [ ]:
(n ! 2*n) % n+1
In [ ]:
(n ! +: n) % >: n
In [ ]:
n=: i.8
In [ ]:
(n ! +: n) % >: n
In [ ]:
cat1=: (! +:) % >:
In [ ]:
cat1 i.8
In [ ]:
n=: i.8
In [ ]:
n ,. cat1 n
In [ ]:
(,. cat1) i.8
In [ ]:
cat1 100
In [ ]:
cat1 x: 100
In [ ]:
cat2=: cat1 @ x:
In [ ]:
cat2 100
In [ ]:
(,. cat2) 100+i.10
In [ ]:
cat2 1000
In [ ]:
$":cat2 1000
In [ ]:
load 'general/misc/format'
In [ ]:
xfmt cat2 1000
Can cat2 be used to generate the 10,000th Catalan number?
Yes - with a fast PC and enough memory. On the authors PC, this calculation takes just under a second and results in a number with 6,015 digits. However, it is near the limit of what can be achieved using this simple formula. If you try this, you might find that your PC runs out of memory, and starts paging memory to hard disk. This slows the calculation down enormously, and should be avoided.
It turns out that you can calculate !n by calculating the exponents in !n of each prime up to n, and this leads to a more efficient technique for computing the Catalan numbers where n is very large.
The idea is that for each prime p up to n, you calculate a list, lp, of the prime powers of p up to n, and then the exponent of p in !n is given by:
```+/ <. n % lp```
To keep numbers small, We will illustrate this for the calculation of !100.
In [ ]:
<. 3 ^. 100
In [ ]:
3 ^ 1 2 3 4 5
In [ ]:
<. 7 ^. 100
In [ ]:
7 ^ 1 2 3
In [ ]:
+/ <. 100 % 3 ^ >: i. <. 3 ^. 100
In [ ]:
a=: !100x
In [ ]:
b=: 3^48x
In [ ]:
a -: b * a <.@% b
In [ ]:
b=: 3^49x
In [ ]:
a -: b * a <.@% b
In [ ]:
pexp=: [: +/ ] <.@% [ ^ >: @ i. @ (<.@^.)
In [ ]:
3 pexp 100
In [ ]:
7 pexp 100
In [ ]:
p: 7 NB. 7th prime
In [ ]:
p: inverse 19 NB. which prime is 19?
In [ ]:
p: i. p: inverse 19 NB. primes 0-6 (=i.7)
In [ ]:
p: i. p: inverse 20 NB. primes 0-7 (=i.8)
In [ ]:
ple=: p: @ i. @ (p: inverse) @ >:
In [ ]:
ple 19
In [ ]:
n=: 100
In [ ]:
ple n
In [ ]:
(ple n) pexp"0 n
In [ ]:
cat3=: 3 : 0
p=. ple +: y
e1=. p pexp"0 +: y
e2=. p pexp"0 y
e3=. p pexp"0 >: y
*/ p ^ x: e1-e2+e3
)
In [ ]:
(cat2 1000) -: cat3 1000
cat3 can be used to calculate the 10,000th Catalan number.
You can try larger numbers, but be warned this may take a long time, or run out of memory. On the PC of the author, cat3 100,000 takes just under 1 second and returns a result with 60,199 digits.
The next section calculates cat3 10000.
In [ ]:
a=: cat3 10000
In [ ]:
$":a
In [ ]: