Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Catalan_numbers
note: Arithmetic operations

View file

@ -0,0 +1,19 @@
<br>
Catalan numbers are a sequence of numbers which can be defined directly:
:<math>C_n = \frac{1}{n+1}{2n\choose n} = \frac{(2n)!}{(n+1)!\,n!} \qquad\mbox{ for }n\ge 0.</math>
Or recursively:
:<math>C_0 = 1 \quad \mbox{and} \quad C_{n+1}=\sum_{i=0}^{n}C_i\,C_{n-i}\quad\text{for }n\ge 0;</math>
Or alternatively (also recursive):
:<math>C_0 = 1 \quad \mbox{and} \quad C_n=\frac{2(2n-1)}{n+1}C_{n-1},</math>
;Task:
Implement at least one of these algorithms and print out the first 15 Catalan numbers with each.
[[Memoization]] &nbsp; is not required, but may be worth the effort when using the second method above.
;Related tasks:
*[[Catalan numbers/Pascal's triangle]]
*[[Evaluate binomial coefficients]]
<br><br>

View file

@ -0,0 +1,4 @@
V c = 1
L(n) 1..15
print(c)
c = 2 * (2 * n - 1) * c I/ (n + 1)

View file

@ -0,0 +1,22 @@
CATALAN CSECT 08/09/2015
USING CATALAN,R15
LA R7,1 c=1
LA R6,1 i=1
LOOPI CH R6,=H'15' do i=1 to 15
BH ELOOPI
XDECO R6,PG edit i
LR R5,R6 i
SLA R5,1 *2
BCTR R5,0 -1
SLA R5,1 *2
MR R4,R7 *c
LA R6,1(R6) i=i+1
DR R4,R6 /i
LR R7,R5 c=2*(2*i-1)*c/(i+1)
XDECO R7,PG+12 edit c
XPRNT PG,24 print
B LOOPI next i
ELOOPI BR R14
PG DS CL24
YREGS
END CATALAN

View file

@ -0,0 +1,32 @@
report z_catalan_numbers.
class catalan_numbers definition.
public section.
class-methods:
get_nth_number
importing
i_n type int4
returning
value(r_catalan_number) type int4.
endclass.
class catalan_numbers implementation.
method get_nth_number.
r_catalan_number = cond int4(
when i_n eq 0
then 1
else reduce int4(
init
result = 1
index = 1
for position = 1 while position <= i_n
next
result = result * 2 * ( 2 * index - 1 ) div ( index + 1 )
index = index + 1 ) ).
endmethod.
endclass.
start-of-selection.
do 15 times.
write / |C({ sy-index - 1 }) = { catalan_numbers=>get_nth_number( sy-index - 1 ) }|.
enddo.

View file

@ -0,0 +1,32 @@
# calculate the first few catalan numbers, using LONG INT values #
# (64-bit quantities in Algol 68G which can handle up to C23) #
# returns n!/k! #
PROC factorial over factorial = ( INT n, k )LONG INT:
IF k > n THEN 0
ELIF k = n THEN 1
ELSE # k < n #
LONG INT f := 1;
FOR i FROM k + 1 TO n DO f *:= i OD;
f
FI # factorial over factorial # ;
# returns n! #
PROC factorial = ( INT n )LONG INT:
BEGIN
LONG INT f := 1;
FOR i FROM 2 TO n DO f *:= i OD;
f
END # factorial # ;
# returnss the nth Catalan number using binomial coefficeients #
# uses the factorial over factorial procedure for a slight optimisation #
# note: Cn = 1/(n+1)(2n n) #
# = (2n)!/((n+1)!n!) #
# = factorial over factorial( 2n, n+1 )/n! #
PROC catalan = ( INT n )LONG INT: IF n < 2 THEN 1 ELSE factorial over factorial( n + n, n + 1 ) OVER factorial( n ) FI;
# show the first few catalan numbers #
FOR i FROM 0 TO 15 DO
print( ( whole( i, -2 ), ": ", whole( catalan( i ), 0 ), newline ) )
OD

View file

@ -0,0 +1,10 @@
begin
% print the catalan numbers up to C15 %
integer Cprev;
Cprev := 1; % C0 %
write( s_w := 0, i_w := 3, 0, ": ", i_w := 9, Cprev );
for n := 1 until 15 do begin
Cprev := round( ( ( ( 4 * n ) - 2 ) / ( n + 1 ) ) * Cprev );
write( s_w := 0, i_w := 3, n, ": ", i_w := 9, Cprev );
end for_n
end.

View file

@ -0,0 +1 @@
{(!2×)÷(!+1)×!}(15)-1

View file

@ -0,0 +1,16 @@
# syntax: GAWK -f CATALAN_NUMBERS.AWK
BEGIN {
for (i=0; i<=15; i++) {
printf("%2d %10d\n",i,catalan(i))
}
exit(0)
}
function catalan(n, ans) {
if (n == 0) {
ans = 1
}
else {
ans = ((2*(2*n-1))/(n+1))*catalan(n-1)
}
return(ans)
}

View file

@ -0,0 +1,20 @@
INCLUDE "D2:REAL.ACT" ;from the Action! Tool Ki
PROC Main()
REAL c,rnom,rden
BYTE n,nom,den
Put(125) PutE() ;clear the screen
IntToReal(1,c)
FOR n=1 TO 15
DO
nom=(n LSH 1-1) LSH 1
den=n+1
IntToReal(nom,rnom)
IntToReal(den,rden)
RealMult(c,rnom,c)
RealDiv(c,rden,c)
PrintF("C(%B)=",n) PrintRE(c)
OD
RETURN

View file

@ -0,0 +1,16 @@
with Ada.Text_IO; use Ada.Text_IO;
procedure Test_Catalan is
function Catalan (N : Natural) return Natural is
Result : Positive := 1;
begin
for I in 1..N loop
Result := Result * 2 * (2 * I - 1) / (I + 1);
end loop;
return Result;
end Catalan;
begin
for N in 0..15 loop
Put_Line (Integer'Image (N) & " =" & Integer'Image (Catalan (N)));
end loop;
end Test_Catalan;

View file

@ -0,0 +1,12 @@
10 HOME : REM 10 CLS for Chipmunk Basic/QBasic
20 DIM c(15)
30 c(0) = 1
40 PRINT 0, c(0)
50 FOR n = 0 TO 14
60 c(n + 1) = 0
70 FOR i = 0 TO n
80 c(n + 1) = c(n + 1) + c(i) * c(n - i)
90 NEXT i
100 PRINT n + 1, c(n + 1)
110 NEXT n
120 END

View file

@ -0,0 +1,11 @@
catalan: function [n][
if? n=0 -> 1
else -> div (catalan n-1) * (4*n)-2 n+1
]
loop 0..15 [i][
print [
pad.right to :string i 5
pad.left to :string catalan i 20
]
]

View file

@ -0,0 +1,20 @@
Loop 15
out .= "`n" Catalan(A_Index)
Msgbox % clipboard := SubStr(out, 2)
catalan( n ) {
; By [VxE]. Returns ((2n)! / ((n + 1)! * n!)) if 0 <= N <= 22 (higher than 22 results in overflow)
If ( n < 3 ) ; values less than 3 are handled specially
Return n < 0 ? "" : n = 0 ? 1 : n
i := 1 ; initialize the accumulator to 1
Loop % n - 1 >> 1 ; build the numerator by multiplying odd values between 2N and N+1
i *= 1 + ( n - A_Index << 1 )
i <<= ( n - 2 >> 1 ) ; multiply the numerator by powers of 2 according to N
Loop % n - 3 >> 1 ; finish up by (integer) dividing by each of the non-cancelling factors
i //= A_Index + 2
Return i
}

View file

@ -0,0 +1,18 @@
DECLARE FUNCTION catalan (n as INTEGER) AS SINGLE
REDIM SHARED results(0) AS SINGLE
FOR x% = 1 TO 15
PRINT x%, catalan (x%)
NEXT
FUNCTION catalan (n as INTEGER) AS SINGLE
IF UBOUND(results) < n THEN REDIM PRESERVE results(n)
IF 0 = n THEN
results(0) = 1
ELSE
results(n) = ((2 * ((2 * n) - 1)) / (n + 1)) * catalan(n - 1)
END IF
catalan = results(n)
END FUNCTION

View file

@ -0,0 +1,33 @@
function factorial(n)
if n = 0 then return 1
return n * factorial(n - 1)
end function
function catalan1(n)
prod = 1
for i = n + 2 to 2 * n
prod *= i
next i
return int(prod / factorial(n))
end function
function catalan2(n)
if n = 0 then return 1
sum = 0
for i = 0 to n - 1
sum += catalan2(i) * catalan2(n - 1 - i)
next i
return sum
end function
function catalan3(n)
if n = 0 then return 1
return catalan3(n - 1) * 2 * (2 * n - 1) \ (n + 1)
end function
print "n", "First", "Second", "Third"
print "-", "-----", "------", "-----"
print
for i = 0 to 15
print i, catalan1(i), catalan2(i), catalan3(i)
next i

View file

@ -0,0 +1,7 @@
10 FOR i% = 1 TO 15
20 PRINT FNcatalan(i%)
30 NEXT
40 END
50 DEF FNcatalan(n%)
60 IF n% = 0 THEN = 1
70 = 2 * (2 * n% - 1) * FNcatalan(n% - 1) / (n% + 1)

View file

@ -0,0 +1,13 @@
Cat{ 0<1, (𝕊-1)×(¯2+4×)÷1+ 𝕩 }
Fact ×´1+
Cat1 { # direct formula
0.5 + (Fact 2×𝕩) ÷ (Fact 𝕩+1) × Fact 𝕩
}
Cat2 { # header based recursion
0: 1;
(𝕊 𝕩-1)×2×(1-˜2×𝕩)÷𝕩+1
}
Cat¨ 15
Cat1¨ 15
Cat2¨ 15

View file

@ -0,0 +1,4 @@
0>:.:000p1>\:00g-#v_v
v 2-1*2p00 :+1g00\< $
> **00g1+/^v,*84,"="<
_^#<`*53:+1>#,.#+5< @

View file

@ -0,0 +1,57 @@
( out$straight
& ( C
=
. ( F
= i prod
. !arg:0&1
| 1:?prod
& 0:?i
& whl
' ( 1+!i:~>!arg:?i
& !i*!prod:?prod
)
& !prod
)
& F$(2*!arg)*(F$(!arg+1)*F$!arg)^-1
)
& -1:?n
& whl
' ( 1+!n:~>15:?n
& out$(str$(C !n " = " C$!n))
)
& out$"recursive, with memoization, without fractions"
& :?seenCs
& ( C
= i sum
. !arg:0&1
| ( !seenCs:? (!arg.?sum) ?
| 0:?sum
& -1:?i
& whl
' ( 1+!i:<!arg:?i
& C$!i*C$(-1+!arg+-1*!i)+!sum:?sum
)
& (!arg.!sum) !seenCs:?seenCs
)
& !sum
)
& -1:?n
& whl
' ( 1+!n:~>15:?n
& out$(str$(C !n " = " C$!n))
)
& out$"recursive, without memoization, with fractions"
& ( C
=
. !arg:0&1
| 2*(2*!arg+-1)*(!arg+1)^-1*C$(!arg+-1)
)
& -1:?n
& whl
' ( 1+!n:~>15:?n
& out$(str$(C !n " = " C$!n))
)
& out$"Using taylor expansion of sqrt(1-4X). (See http://bababadalgharaghtakamminarronnkonnbro.blogspot.in/2012/10/algebraic-type-systems-combinatorial.html)"
& out$(1+(1+-1*tay$((1+-4*X)^1/2,X,16))*(2*X)^-1+-1)
& out$
);

View file

@ -0,0 +1,68 @@
straight
C0 = 1
C1 = 1
C2 = 2
C3 = 5
C4 = 14
C5 = 42
C6 = 132
C7 = 429
C8 = 1430
C9 = 4862
C10 = 16796
C11 = 58786
C12 = 208012
C13 = 742900
C14 = 2674440
C15 = 9694845
recursive, with memoization, without fractions
C0 = 1
C1 = 1
C2 = 2
C3 = 5
C4 = 14
C5 = 42
C6 = 132
C7 = 429
C8 = 1430
C9 = 4862
C10 = 16796
C11 = 58786
C12 = 208012
C13 = 742900
C14 = 2674440
C15 = 9694845
recursive, without memoization, with fractions
C0 = 1
C1 = 1
C2 = 2
C3 = 5
C4 = 14
C5 = 42
C6 = 132
C7 = 429
C8 = 1430
C9 = 4862
C10 = 16796
C11 = 58786
C12 = 208012
C13 = 742900
C14 = 2674440
C15 = 9694845
Using taylor expansion of sqrt(1-4X). (See http://bababadalgharaghtakamminarronnkonnbro.blogspot.in/2012/10/algebraic-type-systems-combinatorial.html)
1
+ X
+ 2*X^2
+ 5*X^3
+ 14*X^4
+ 42*X^5
+ 132*X^6
+ 429*X^7
+ 1430*X^8
+ 4862*X^9
+ 16796*X^10
+ 58786*X^11
+ 208012*X^12
+ 742900*X^13
+ 2674440*X^14
+ 9694845*X^15

View file

@ -0,0 +1,9 @@
catalan = { n |
true? n == 0
{ 1 }
{ (2 * ( 2 * n - 1) / ( n + 1 )) * catalan(n - 1) }
}
0.to 15 { n |
p "#{n} - #{catalan n}"
}

View file

@ -0,0 +1,60 @@
#if !defined __ALGORITHMS_H__
#define __ALGORITHMS_H__
namespace rosetta
{
namespace catalanNumbers
{
namespace detail
{
class Factorial
{
public:
unsigned long long operator()(unsigned n)const;
};
class BinomialCoefficient
{
public:
unsigned long long operator()(unsigned n, unsigned k)const;
};
} //namespace detail
class CatalanNumbersDirectFactorial
{
public:
CatalanNumbersDirectFactorial();
unsigned long long operator()(unsigned n)const;
private:
detail::Factorial factorial;
};
class CatalanNumbersDirectBinomialCoefficient
{
public:
CatalanNumbersDirectBinomialCoefficient();
unsigned long long operator()(unsigned n)const;
private:
detail::BinomialCoefficient binomialCoefficient;
};
class CatalanNumbersRecursiveSum
{
public:
CatalanNumbersRecursiveSum();
unsigned long long operator()(unsigned n)const;
};
class CatalanNumbersRecursiveFraction
{
public:
CatalanNumbersRecursiveFraction();
unsigned long long operator()(unsigned n)const;
};
} //namespace catalanNumbers
} //namespace rosetta
#endif //!defined __ALGORITHMS_H__

View file

@ -0,0 +1,101 @@
#include <iostream>
using std::cout;
using std::endl;
#include <cmath>
using std::floor;
#include "algorithms.h"
using namespace rosetta::catalanNumbers;
CatalanNumbersDirectFactorial::CatalanNumbersDirectFactorial()
{
cout<<"Direct calculation using the factorial"<<endl;
}
unsigned long long CatalanNumbersDirectFactorial::operator()(unsigned n)const
{
if(n>1)
{
unsigned long long nFac = factorial(n);
return factorial(2 * n) / ((n + 1) * nFac * nFac);
}
else
{
return 1;
}
}
CatalanNumbersDirectBinomialCoefficient::CatalanNumbersDirectBinomialCoefficient()
{
cout<<"Direct calculation using a binomial coefficient"<<endl;
}
unsigned long long CatalanNumbersDirectBinomialCoefficient::operator()(unsigned n)const
{
if(n>1)
return double(1) / (n + 1) * binomialCoefficient(2 * n, n);
else
return 1;
}
CatalanNumbersRecursiveSum::CatalanNumbersRecursiveSum()
{
cout<<"Recursive calculation using a sum"<<endl;
}
unsigned long long CatalanNumbersRecursiveSum::operator()(unsigned n)const
{
if(n>1)
{
const unsigned n_ = n - 1;
unsigned long long sum = 0;
for(unsigned i = 0; i <= n_; i++)
sum += operator()(i) * operator()(n_ - i);
return sum;
}
else
{
return 1;
}
}
CatalanNumbersRecursiveFraction::CatalanNumbersRecursiveFraction()
{
cout<<"Recursive calculation using a fraction"<<endl;
}
unsigned long long CatalanNumbersRecursiveFraction::operator()(unsigned n)const
{
if(n>1)
return (double(2 * (2 * n - 1)) / (n + 1)) * operator()(n-1);
else
return 1;
}
unsigned long long detail::Factorial::operator()(unsigned n)const
{
if(n>1)
return n * operator()(n-1);
else
return 1;
}
unsigned long long detail::BinomialCoefficient::operator()(unsigned n, unsigned k)const
{
if(k == 0)
return 1;
if(n == 0)
return 0;
double product = 1;
for(unsigned i = 1; i <= k; i++)
product *= (double(n - (k - i)) / i);
return (unsigned long long)(floor(product + 0.5));
}

View file

@ -0,0 +1,26 @@
#if !defined __TESTER_H__
#define __TESTER_H__
#include <iostream>
namespace rosetta
{
namespace catalanNumbers
{
template <int N, typename A>
class Test
{
public:
static void Do()
{
A algorithm;
for(int i = 0; i <= N; i++)
std::cout<<"C("<<i<<")\t= "<<algorithm(i)<<std::endl;
}
};
} //namespace catalanNumbers
} //namespace rosetta
#endif //!defined __TESTER_H__

View file

@ -0,0 +1,12 @@
#include "algorithms.h"
#include "tester.h"
using namespace rosetta::catalanNumbers;
int main(int argc, char* argv[])
{
Test<10, CatalanNumbersDirectFactorial>::Do();
Test<15, CatalanNumbersDirectBinomialCoefficient>::Do();
Test<15, CatalanNumbersRecursiveFraction>::Do();
Test<15, CatalanNumbersRecursiveSum>::Do();
return 0;
}

View file

@ -0,0 +1,114 @@
namespace CatalanNumbers
{
/// <summary>
/// Class that holds all options.
/// </summary>
public class CatalanNumberGenerator
{
private static double Factorial(double n)
{
if (n == 0)
return 1;
return n * Factorial(n - 1);
}
public double FirstOption(double n)
{
const double topMultiplier = 2;
return Factorial(topMultiplier * n) / (Factorial(n + 1) * Factorial(n));
}
public double SecondOption(double n)
{
if (n == 0)
{
return 1;
}
double sum = 0;
double i = 0;
for (; i <= (n - 1); i++)
{
sum += SecondOption(i) * SecondOption((n - 1) - i);
}
return sum;
}
public double ThirdOption(double n)
{
if (n == 0)
{
return 1;
}
return ((2 * (2 * n - 1)) / (n + 1)) * ThirdOption(n - 1);
}
}
}
// Program.cs
using System;
using System.Configuration;
// Main program
// Be sure to add the following to the App.config file and add a reference to System.Configuration:
// <?xml version="1.0" encoding="utf-8" ?>
// <configuration>
// <appSettings>
// <clear/>
// <add key="MaxCatalanNumber" value="50"/>
// </appSettings>
// </configuration>
namespace CatalanNumbers
{
class Program
{
static void Main(string[] args)
{
CatalanNumberGenerator generator = new CatalanNumberGenerator();
int i = 0;
DateTime initial;
DateTime final;
TimeSpan ts;
try
{
initial = DateTime.Now;
for (; i <= Convert.ToInt32(ConfigurationManager.AppSettings["MaxCatalanNumber"]); i++)
{
Console.WriteLine("CatalanNumber({0}):{1}", i, generator.FirstOption(i));
}
final = DateTime.Now;
ts = final - initial;
Console.WriteLine("It took {0}.{1} to execute\n", ts.Seconds, ts.Milliseconds);
i = 0;
initial = DateTime.Now;
for (; i <= Convert.ToInt32(ConfigurationManager.AppSettings["MaxCatalanNumber"]); i++)
{
Console.WriteLine("CatalanNumber({0}):{1}", i, generator.SecondOption(i));
}
final = DateTime.Now;
ts = final - initial;
Console.WriteLine("It took {0}.{1} to execute\n", ts.Seconds, ts.Milliseconds);
i = 0;
initial = DateTime.Now;
for (; i <= Convert.ToInt32(ConfigurationManager.AppSettings["MaxCatalanNumber"]); i++)
{
Console.WriteLine("CatalanNumber({0}):{1}", i, generator.ThirdOption(i));
}
final = DateTime.Now;
ts = final - initial;
Console.WriteLine("It took {0}.{1} to execute", ts.Seconds, ts.Milliseconds, ts.TotalMilliseconds);
Console.ReadLine();
}
catch (Exception ex)
{
Console.WriteLine("Stopped at index {0}:", i);
Console.WriteLine(ex.Message);
Console.ReadLine();
}
}
}
}

View file

@ -0,0 +1,46 @@
#include <stdio.h>
typedef unsigned long long ull;
ull binomial(ull m, ull n)
{
ull r = 1, d = m - n;
if (d > n) { n = d; d = m - n; }
while (m > n) {
r *= m--;
while (d > 1 && ! (r%d) ) r /= d--;
}
return r;
}
ull catalan1(int n) {
return binomial(2 * n, n) / (1 + n);
}
ull catalan2(int n) {
int i;
ull r = !n;
for (i = 0; i < n; i++)
r += catalan2(i) * catalan2(n - 1 - i);
return r;
}
ull catalan3(int n)
{
return n ? 2 * (2 * n - 1) * catalan3(n - 1) / (1 + n) : 1;
}
int main(void)
{
int i;
puts("\tdirect\tsumming\tfrac");
for (i = 0; i < 16; i++) {
printf("%d\t%llu\t%llu\t%llu\n", i,
catalan1(i), catalan2(i), catalan3(i));
}
return 0;
}

View file

@ -0,0 +1,14 @@
catalan = iter (amount: int) yields (int)
c: int := 1
for n: int in int$from_to(1, amount) do
yield(c)
c := (4*n-2)*c/(n+1)
end
end catalan
start_up = proc ()
po: stream := stream$primary_output()
for n: int in catalan(15) do
stream$putl(po, int$unparse(n))
end
end start_up

View file

@ -0,0 +1,8 @@
10 FOR i = 1 TO 15
20 PRINT i;" ";catalan(i)
30 NEXT
40 END
50 SUB catalan(n)
60 catalan = 1
70 IF n <> 0 THEN catalan = ((2*((2*n)-1))/(n+1))*catalan(n-1)
80 END SUB

View file

@ -0,0 +1,17 @@
(def ! (memoize #(apply * (range 1 (inc %)))))
(defn catalan-numbers-direct []
(map #(/ (! (* 2 %))
(* (! (inc %)) (! %))) (range)))
(def catalan-numbers-recursive
#(->> [1 1] ; [c0 n1]
(iterate (fn [[c n]]
[(* 2 (dec (* 2 n)) (/ (inc n)) c) (inc n)]) ,)
(map first ,)))
user> (take 15 (catalan-numbers-direct))
(1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440)
user> (take 15 (catalan-numbers-recursive))
(1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440)

View file

@ -0,0 +1,28 @@
(defun catalan1 (n)
;; factorial. CLISP actually has "!" defined for this
(labels ((! (x) (if (zerop x) 1 (* x (! (1- x))))))
(/ (! (* 2 n)) (! (1+ n)) (! n))))
;; cache
(defparameter *catalans* (make-array 5
:fill-pointer 0
:adjustable t
:element-type 'integer))
(defun catalan2 (n)
(if (zerop n) 1
;; check cache
(if (< n (length *catalans*)) (aref *catalans* n)
(loop with c = 0 for i from 0 to (1- n) collect
(incf c (* (catalan2 i) (catalan2 (- n 1 i))))
;; lower values always get calculated first, so
;; vector-push-extend is safe
finally (progn (vector-push-extend c *catalans*) (return c))))))
(defun catalan3 (n)
(if (zerop n) 1 (/ (* 2 (+ n n -1) (catalan3 (1- n))) (1+ n))))
;;; test all three methods
(loop for f in (list #'catalan1 #'catalan2 #'catalan3)
for i from 1 to 3 do
(format t "~%Method ~d:~%" i)
(dotimes (i 16) (format t "C(~2d) = ~d~%" i (funcall f i))))

View file

@ -0,0 +1,20 @@
include "cowgol.coh";
sub catalan(n: uint32): (c: uint32) is
c := 1;
var i: uint32 := 1;
while i <= n loop
c := (4*i-2)*c/(i+1);
i := i+1;
end loop;
end sub;
var i: uint8 := 0;
while i < 15 loop
print("catalan(");
print_i8(i);
print(") = ");
print_i32(catalan(i as uint32));
print_nl();
i := i+1;
end loop;

View file

@ -0,0 +1,19 @@
dim c[16]
let c[0] = 1
for n = 0 to 15
let p = n + 1
let c[p] = 0
for i = 0 to n
let q = n - i
let c[p] = c[p] + c[i] * c[q]
next i
print n, " ", c[n]
next n

View file

@ -0,0 +1,41 @@
require "big"
require "benchmark"
def factorial(n : BigInt) : BigInt
(1..n).product(1.to_big_i)
end
def factorial(n : Int32 | Int64)
factorial n.to_big_i
end
# direct
def catalan_direct(n)
factorial(2*n) / (factorial(n + 1) * factorial(n))
end
# recursive
def catalan_rec1(n)
return 1 if n == 0
(0...n).reduce(0) do |sum, i|
sum + catalan_rec1(i) * catalan_rec1(n - 1 - i)
end
end
def catalan_rec2(n)
return 1 if n == 0
2*(2*n - 1) * catalan_rec2(n - 1) / (n + 1)
end
# performance and results
Benchmark.bm do |b|
b.report("catalan_direct") { 16.times { |n| catalan_direct(n) } }
b.report("catalan_rec1") { 16.times { |n| catalan_rec1(n) } }
b.report("catalan_rec2") { 16.times { |n| catalan_rec2(n) } }
end
puts "\n direct rec1 rec2"
16.times { |n| puts "%2d :%9d%9d%9d" % [n, catalan_direct(n), catalan_rec1(n), catalan_rec2(n)] }

View file

@ -0,0 +1,20 @@
import std.stdio, std.algorithm, std.bigint, std.functional, std.range;
auto product(R)(R r) { return reduce!q{a * b}(1.BigInt, r); }
const cats1 = sequence!((a, n) => iota(n+2, 2*n+1).product / iota(1, n+1).product)(1);
BigInt cats2a(in uint n) {
alias mcats2a = memoize!cats2a;
if (n == 0) return 1.BigInt;
return n.iota.map!(i => mcats2a(i) * mcats2a(n - 1 - i)).sum;
}
const cats2 = sequence!((a, n) => n.cats2a);
const cats3 = recurrence!q{ (4*n - 2) * a[n - 1] / (n + 1) }(1.BigInt);
void main() {
foreach (cats; TypeTuple!(cats1, cats2, cats3))
cats.take(15).writeln;
}

View file

@ -0,0 +1,99 @@
[Calculation of Catalan numbers.
EDSAC program, Initial Orders 2.]
[Define where to store the list of Catalan numbers.]
T 54 K [store address in location 54, so that values
are accessed by code letter C (for Catalan)]
P 200 F [<------ address here]
[Modification of library subroutine P7.
Prints signed integer up to 10 digits, right-justified.
54 storage locations; working position 4D.
Must be loaded at an even address.
Input: Number is at 0D.]
T 56 K
GKA3FT42@A47@T31@ADE10@T31@A48@T31@SDTDH44#@NDYFLDT4DS43@TF
H17@S17@A43@G23@UFS43@T1FV4DAFG50@SFLDUFXFOFFFSFL4FT4DA49@T31@
A1FA43@G20@XFP1024FP610D@524D!FO46@O26@XFO46@SFL8FT4DE39@
[Main routine]
T 120 K [load at 120]
G K [set @ (theta) to load address]
[Variables]
[0] P F [index of Catalan number]
[Constants]
[1] P 7 D [maximum index required]
[2] P D [single-word 1]
[3] P 2 F [to change addresses by 2]
[4] H #C [these 3 are used to manufacture EDSAC orders]
[5] T #C
[6] V #C
[7] K 4096 F [(1) add to change T order into H order
(2) teleprinter null]
[8] # F [figures shift]
[9] ! F [space]
[10] @ F [carriage return]
[11] & F [line feed]
[Enter with acc = 0]
[12] O 8 @ [set teleprinter to figures]
T 4 D [clear 5F and sandwich bit]
A 2 @ [load single-word 1]
T 4 F [store as double word at 4D; clear acc]
[Here with index in acc, Catalan number in 4D]
[16] U @ [store index]
L 1 F [times 4 by shifting]
A 5 @ [make T order to store Catalan number]
U 27 @ [plant in code]
A 7 @ [make H order with same address]
U 45 @ [plant in code]
S 47 @ [make A order with same address]
T 34 @ [plant in code]
A 6 @ [load V order for start of list]
T 46 @ [plant in code]
A 4 D [Catalan number from temp store]
[27] T #C [store in list (manufactured order)]
T D [clear 1F and sandwich bit]
A @ [load single-word index]
T F [store as double word at 0D]
[31] A 31 @ [for return from print subroutine]
G 56 F [print index]
O 9 @ [followed by space]
[34] A #C [load Catalan number (manufactured order)]
T D [to 0D for printing]
[36] A 36 @ [for return from print subroutine]
G 56 F [print Catalan number]
O 10 @ [followed by new line]
O 11 @
T 4 D [clear partial sum]
A @ [load index]
S 1 @ [reached the maximum?]
E 64 @ [if so, jump to exit]
[Inner loop to compute sum of products C{i}*C(n-1}]
[44] T F [clear acc]
[45] H #C [C{n-i} to mult reg (manufactured order)]
[46] V #C [acc := C{i}*C{n-i} (manufactiured order)]
[Multiply product by 2^34 (see preamble). The 'L F' order is
also exploited above to convert an H order into an A order.]
[47] L F [shift acc left by 13 (the maximum available)]
L F [shift 13 more]
L 64 F [shift 8 more, total 34]
A 4 D [add partial sum]
T 4 D [update partial sum]
A 46 @ [inc i in V order]
A 3 @
T 46 @
A 45 @ [dec (n - i) in H order]
S 3 @
U 45 @
S 4 @ [is (n - i) now negative?]
E 44 @ [if not, loop back]
[Here with latest Catalan number in temp store 4D]
T F [clear acc]
A @ [load index]
A 2 @ [add 1]
E 16 @ [back to start of outer loop]
[64] O 7 @ [exit; print null to flush teleprinter buffer]
Z F [stop]
E 12 Z [define entry point]
P F [acc = 0 on entry]

View file

@ -0,0 +1,15 @@
PROGRAM CATALAN
PROCEDURE CATALAN(N->RES)
RES=1
FOR I=1 TO N DO
RES=RES*2*(2*I-1)/(I+1)
END FOR
END PROCEDURE
BEGIN
FOR N=0 TO 15 DO
CATALAN(N->RES)
PRINT(N;"=";RES)
END FOR
END PROGRAM

View file

@ -0,0 +1,12 @@
proc catalan n . ans .
if n = 0
ans = 1
else
call catalan n - 1 h
ans = 2 * (2 * n - 1) * h div (1 + n)
.
.
for i = 0 to 14
call catalan i h
print h
.

View file

@ -0,0 +1,37 @@
(lib 'sequences)
(lib 'bigint)
(lib 'math)
;; function definition
(define (C1 n) (/ (factorial (* n 2)) (factorial (1+ n)) (factorial n)))
(for ((i [1 .. 16])) (write (C1 i)))
→ 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845
;; using a recursive procedure with memoization
(define (C2 n) ;; ( Σ ...)is the same as (sigma ..)
(Σ (lambda(i) (* (C2 i) (C2 (- n i 1)))) 0 (1- n)))
(remember 'C2 #(1)) ;; first term defined here
(for ((i [1 .. 16])) (write (C2 i)))
→ 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845
;; using procrastinators = infinite sequence
(define (catalan n acc) (/ (* acc 2 (1- (* 2 n))) (1+ n)))
(define C3 (scanl catalan 1 [1 ..]))
(take C3 15)
→ (1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845)
;; the same, using infix notation
(lib 'match)
(load 'infix.glisp)
(define (catalan n acc) ((2 * acc * ( 2 * n - 1)) / (n + 1)))
(define C3 (scanl catalan 1 [1 ..]))
(take C3 15)
→ (1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845)
;; or
(for ((c C3) (i 15)) (write c))
→ 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845

View file

@ -0,0 +1,35 @@
class
APPLICATION
create
make
feature {NONE}
make
do
across
0 |..| 14 as c
loop
io.put_double (nth_catalan_number (c.item))
io.new_line
end
end
nth_catalan_number (n: INTEGER): DOUBLE
--'n'th number in the sequence of Catalan numbers.
require
n_not_negative: n >= 0
local
s, t: DOUBLE
do
if n = 0 then
Result := 1.0
else
t := 4 * n.to_double - 2
s := n.to_double + 1
Result := t / s * nth_catalan_number (n - 1)
end
end
end

View file

@ -0,0 +1,23 @@
defmodule Catalan do
def cat(n), do: div( factorial(2*n), factorial(n+1) * factorial(n) )
defp factorial(n), do: fac1(n,1)
defp fac1(0, acc), do: acc
defp fac1(n, acc), do: fac1(n-1, n*acc)
def cat_r1(0), do: 1
def cat_r1(n), do: Enum.sum(for i <- 0..n-1, do: cat_r1(i) * cat_r1(n-1-i))
def cat_r2(0), do: 1
def cat_r2(n), do: div(cat_r2(n-1) * 2 * (2*n - 1), n + 1)
def test do
range = 0..14
:io.format "Directly:~n~p~n", [(for n <- range, do: cat(n))]
:io.format "1st recusive method:~n~p~n", [(for n <- range, do: cat_r1(n))]
:io.format "2nd recusive method:~n~p~n", [(for n <- range, do: cat_r2(n))]
end
end
Catalan.test

View file

@ -0,0 +1,30 @@
-module(catalan).
-export([test/0]).
cat(N) ->
factorial(2 * N) div (factorial(N+1) * factorial(N)).
factorial(N) ->
fac1(N,1).
fac1(0,Acc) ->
Acc;
fac1(N,Acc) ->
fac1(N-1, N * Acc).
cat_r1(0) ->
1;
cat_r1(N) ->
lists:sum([cat_r1(I)*cat_r1(N-1-I) || I <- lists:seq(0,N-1)]).
cat_r2(0) ->
1;
cat_r2(N) ->
cat_r2(N - 1) * (2 * ((2 * N) - 1)) div (N + 1).
test() ->
TestList = lists:seq(0,14),
io:format("Directly:\n~p\n",[[cat(N) || N <- TestList]]),
io:format("1st recusive method:\n~p\n",[[cat_r1(N) || N <- TestList]]),
io:format("2nd recusive method:\n~p\n",[[cat_r2(N) || N <- TestList]]).

View file

@ -0,0 +1,23 @@
--Catalan number task from Rosetta Code wiki
--User:Lnettnay
--function from factorial task
function factorial(integer n)
atom f = 1
while n > 1 do
f *= n
n -= 1
end while
return f
end function
function catalan(integer n)
atom numerator = factorial(2 * n)
atom denominator = factorial(n+1)*factorial(n)
return numerator/denominator
end function
for i = 0 to 15 do
? catalan(i)
end for

View file

@ -0,0 +1 @@
Seq.unfold(fun (c,n) -> let cc = 2*(2*n-1)*c/(n+1) in Some(c,(cc,n+1))) (1,1) |> Seq.take 15 |> Seq.iter (printf "%i, ")

View file

@ -0,0 +1,5 @@
USING: kernel math math.combinatorics prettyprint ;
: catalan ( n -- n ) [ 1 + recip ] [ 2 * ] [ nCk * ] tri ;
15 [ catalan . ] each-integer

View file

@ -0,0 +1,10 @@
USING: kernel math prettyprint sequences ;
: next ( seq -- newseq )
[ ] [ last ] [ length ] tri
[ 2 * 1 - 2 * ] [ 1 + ] bi /
* suffix ;
: Catalan ( n -- seq ) V{ 1 } swap 1 - [ next ] times ;
15 Catalan .

View file

@ -0,0 +1,52 @@
class Main
{
static Int factorial (Int n)
{
Int res := 1
if (n>1)
(2..n).each |i| { res *= i }
return res
}
static Int catalanA (Int n)
{
return factorial(2*n)/(factorial(n+1) * factorial(n))
}
static Int catalanB (Int n)
{
if (n == 0)
{
return 1
}
else
{
sum := 0
n.times |i| { sum += catalanB(i) * catalanB(n-1-i) }
return sum
}
}
static Int catalanC (Int n)
{
if (n == 0)
{
return 1
}
else
{
return catalanC(n-1)*2*(2*n-1)/(n+1)
}
}
public static Void main ()
{
(1..15).each |n|
{
echo (n.toStr.padl(4) +
catalanA(n).toStr.padl(10) +
catalanB(n).toStr.padl(10) +
catalanC(n).toStr.padl(10))
}
}
}

View file

@ -0,0 +1,2 @@
Func Catalan(n)=(2*n)!/((n+1)!*n!).;
for i=1 to 15 do !Catalan(i);!' ' od;

View file

@ -0,0 +1 @@
: catalan ( n -- ) 1 swap 1+ 1 do dup cr . i 2* 1- 2* i 1+ */ loop drop ;

View file

@ -0,0 +1,44 @@
program main
!=======================================================================================
implicit none
!=== Local data
integer :: n
!=== External procedures
double precision, external :: catalan_numbers
!=== Execution =========================================================================
write(*,'(1x,a)')'==============='
write(*,'(5x,a,6x,a)')'n','c(n)'
write(*,'(1x,a)')'---------------'
do n = 0, 14
write(*,'(1x,i5,i10)') n, int(catalan_numbers(n))
enddo
write(*,'(1x,a)')'==============='
!=======================================================================================
end program main
!BL
!BL
!BL
double precision recursive function catalan_numbers(n) result(value)
!=======================================================================================
implicit none
!=== Input, ouput data
integer, intent(in) :: n
!=== Execution =========================================================================
if ( n .eq. 0 ) then
value = 1
else
value = ( 2.0d0 * dfloat(2 * n - 1) / dfloat( n + 1 ) ) * catalan_numbers(n-1)
endif
!=======================================================================================
end function catalan_numbers

View file

@ -0,0 +1,38 @@
' FB 1.05.0 Win64
Function factorial(n As UInteger) As UInteger
If n = 0 Then Return 1
Return n * factorial(n - 1)
End Function
Function catalan1(n As UInteger) As UInteger
Dim prod As UInteger = 1
For i As UInteger = n + 2 To 2 * n
prod *= i
Next
Return prod / factorial(n)
End Function
Function catalan2(n As UInteger) As UInteger
If n = 0 Then Return 1
Dim sum As UInteger = 0
For i As UInteger = 0 To n - 1
sum += catalan2(i) * catalan2(n - 1 - i)
Next
Return sum
End Function
Function catalan3(n As UInteger) As UInteger
If n = 0 Then Return 1
Return catalan3(n - 1) * 2 * (2 * n - 1) \ (n + 1)
End Function
Print "n", "First", "Second", "Third"
Print "-", "-----", "------", "-----"
Print
For i As UInteger = 0 To 15
Print i, catalan1(i), catalan2(i), catalan3(i)
Next
Print
Print "Press any key to quit"
Sleep

View file

@ -0,0 +1,3 @@
catalan[n] := binomial[2n,n]/(n+1)
for n = 0 to 15
println[catalan[n]]

View file

@ -0,0 +1,22 @@
import integers.choose
import util.TextTable
def
catalan( n ) = choose( 2n, n )/(n + 1)
catalan2( n ) = product( (n + k)/k | k <- 2..n )
catalan3( 0 ) = 1
catalan3( n ) = 2*(2n - 1)/(n + 1)*catalan3( n - 1 )
t = TextTable()
t.header( 'n', 'definition', 'product', 'recursive' )
t.line()
for i <- 1..4
t.rightAlignment( i )
for i <- 0..15
t.row( i, catalan(i), catalan2(i), catalan3(i) )
println( t )

View file

@ -0,0 +1,47 @@
include "NSLog.incl"
local fn Factorial( n as NSInteger ) as UInt64
UInt64 sum = 0
if n = 0 then sum = 1 : exit fn
sum = n * fn Factorial( n - 1 )
end fn = sum
local fn Catalan1( n as NSInteger ) as UInt64
UInt64 product = 1, result
NSUInteger i
for i = n + 2 to 2 * n
product = product * i
next
result = product / fn Factorial( n )
end fn = result
local fn Catalan2( n as NSInteger ) as UInt64
UInt64 sum = 0
NSUInteger i
if n = 0 then sum = 1 : exit fn
for i = 0 to n - 1
sum += fn Catalan2(i) * fn Catalan2( n - 1 - i )
next
end fn = sum
local fn Catalan3( n as NSInteger ) as UInt64
UInt64 result
if n = 0 then result = 1 : exit fn
result = fn Catalan3( n - 1 ) * 2 * ( 2 * n - 1 ) / ( n + 1 )
end fn = result
NSUInteger i
for i = 0 to 19
if( i < 16 )
NSLog( @"%3d.\t\t%7llu\t\t%12llu\t\t%12llu", i, fn Catalan1( i ), fn Catalan2( i ), fn Catalan3( i ) )
else
NSLog( @"%3d.\t\t%@\t\t%12llu\t\t%12llu", i, @"[-err-]", fn Catalan2( i ), fn Catalan3( i ) )
end if
next
HandleEvents

View file

@ -0,0 +1,31 @@
Catalan1 := n -> Binomial(2*n, n) - Binomial(2*n, n - 1);
Catalan2 := n -> Binomial(2*n, n)/(n + 1);
Catalan3 := function(n)
local k, c;
c := 1;
k := 0;
while k < n do
k := k + 1;
c := 2*(2*k - 1)*c/(k + 1);
od;
return c;
end;
Catalan4_memo := [1];
Catalan4 := function(n)
if not IsBound(Catalan4_memo[n + 1]) then
Catalan4_memo[n + 1] := Sum([0 .. n - 1], i -> Catalan4(i)*Catalan4(n - 1 - i));
fi;
return Catalan4_memo[n + 1];
end;
# The first fifteen: 0 to 14 !
List([0 .. 14], Catalan1);
List([0 .. 14], Catalan2);
List([0 .. 14], Catalan3);
List([0 .. 14], Catalan4);
# Same output for all four:
# [ 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440 ]

View file

@ -0,0 +1,12 @@
100 REM Catalan numbers
110 DIM C(15)
120 C(0) = 1
130 PRINT 0, C(0)
140 FOR N = 0 TO 14
150 C(N + 1) = 0
160 FOR I = 0 TO N
170 C(N + 1) = C(N + 1) + C(I) * C(N - I)
180 NEXT I
190 PRINT N + 1, C(N + 1)
200 NEXT N
210 END

View file

@ -0,0 +1,13 @@
package main
import (
"fmt"
"math/big"
)
func main() {
var b, c big.Int
for n := int64(0); n < 15; n++ {
fmt.Println(c.Div(b.Binomial(n*2, n), c.SetInt64(n+1)))
}
}

View file

@ -0,0 +1,27 @@
package main
import (
"fmt"
"math/big"
)
func c(n int64) *big.Int {
if n == 0 {
return big.NewInt(1)
} else {
var t1, t2, t3, t4, t5, t6 big.Int
t1.Mul(big.NewInt(2), big.NewInt(n))
t2.Sub(&t1, big.NewInt(1))
t3.Mul(big.NewInt(2), &t2)
t4.Add(big.NewInt(n), big.NewInt(1))
t5.Mul(&t3, c(n-1))
t6.Div(&t5, &t4)
return &t6
}
}
func main() {
for n := int64(1); n < 16; n++ {
fmt.Println(c(n))
}
}

View file

@ -0,0 +1,23 @@
class Catalan
{
public static void main(String[] args)
{
BigInteger N = 15;
BigInteger k,n,num,den;
BigInteger catalan;
print(1);
for(n=2;n<=N;n++)
{
num = 1;
den = 1;
for(k=2;k<=n;k++)
{
num = num*(n+k);
den = den*k;
catalan = num/den;
}
println(catalan);
}
}
}

View file

@ -0,0 +1,17 @@
PROCEDURE Main()
LOCAL i
FOR i := 0 to 15
? PadL( i, 2 ) + ": " + hb_StrFormat("%d", Catalan( i ))
NEXT
RETURN
STATIC FUNCTION Catalan( n )
LOCAL i, nCatalan := 1
FOR i := 1 TO n
nCatalan := nCatalan * 2 * (2 * i - 1) / (i + 1)
NEXT
RETURN nCatalan

View file

@ -0,0 +1,24 @@
-- Three infinite lists, corresponding to the three
-- definitions in the problem statement.
cats1 :: [Integer]
cats1 =
(div . product . (enumFromTo . (2 +) <*> (2 *)))
<*> (product . enumFromTo 1) <$> [0 ..]
cats2 :: [Integer]
cats2 =
1 :
fmap
(\n -> sum (zipWith (*) (reverse (take n cats2)) cats2))
[1 ..]
cats3 :: [Integer]
cats3 =
scanl
(\c n -> c * 2 * (2 * n - 1) `div` succ n)
1
[1 ..]
main :: IO ()
main = mapM_ (print . take 15) [cats1, cats2, cats3]

View file

@ -0,0 +1,12 @@
procedure main()
every writes(catalan(0 to 14)," ")
end
procedure catalan(n) # return catalan(n) or fail
static M
initial M := table()
n=0 & return 1
if n > 0 then
return (n = 1) | \M[n] | ( M[n] := (2*(2*n-1)*catalan(n-1))/(n+1))
end

View file

@ -0,0 +1,2 @@
((! +:) % >:) i.15x
1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440

View file

@ -0,0 +1,108 @@
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class CatlanNumbers {
public static void main(String[] args) {
Catlan f1 = new Catlan1();
Catlan f2 = new Catlan2();
Catlan f3 = new Catlan3();
System.out.printf(" Formula 1 Formula 2 Formula 3%n");
for ( int n = 0 ; n <= 15 ; n++ ) {
System.out.printf("C(%2d) = %,12d %,12d %,12d%n", n, f1.catlin(n), f2.catlin(n), f3.catlin(n));
}
}
private static interface Catlan {
public BigInteger catlin(long n);
}
private static class Catlan1 implements Catlan {
// C(n) = (2n)! / (n+1)!n!
@Override
public BigInteger catlin(long n) {
List<Long> numerator = new ArrayList<>();
for ( long k = n+2 ; k <= 2*n ; k++ ) {
numerator.add(k);
}
List<Long> denominator = new ArrayList<>();
for ( long k = 2 ; k <= n ; k++ ) {
denominator.add(k);
}
for ( int i = numerator.size()-1 ; i >= 0 ; i-- ) {
for ( int j = denominator.size()-1 ; j >= 0 ; j-- ) {
if ( denominator.get(j) == 1 ) {
continue;
}
if ( numerator.get(i) % denominator.get(j) == 0 ) {
long val = numerator.get(i) / denominator.get(j);
numerator.set(i, val);
denominator.remove(denominator.get(j));
if ( val == 1 ) {
break;
}
}
}
}
BigInteger catlin = BigInteger.ONE;
for ( int i = 0 ; i < numerator.size() ; i++ ) {
catlin = catlin.multiply(BigInteger.valueOf(numerator.get(i)));
}
for ( int i = 0 ; i < denominator.size() ; i++ ) {
catlin = catlin.divide(BigInteger.valueOf(denominator.get(i)));
}
return catlin;
}
}
private static class Catlan2 implements Catlan {
private static Map<Long,BigInteger> CACHE = new HashMap<>();
static {
CACHE.put(0L, BigInteger.ONE);
}
// C(0) = 1, C(n+1) = sum(i=0..n,C(i)*C(n-i))
@Override
public BigInteger catlin(long n) {
if ( CACHE.containsKey(n) ) {
return CACHE.get(n);
}
BigInteger catlin = BigInteger.ZERO;
n--;
for ( int i = 0 ; i <= n ; i++ ) {
//System.out.println("n = " + n + ", i = " + i + ", n-i = " + (n-i));
catlin = catlin.add(catlin(i).multiply(catlin(n-i)));
}
CACHE.put(n+1, catlin);
return catlin;
}
}
private static class Catlan3 implements Catlan {
private static Map<Long,BigInteger> CACHE = new HashMap<>();
static {
CACHE.put(0L, BigInteger.ONE);
}
// C(0) = 1, C(n+1) = 2*(2n-1)*C(n-1)/(n+1)
@Override
public BigInteger catlin(long n) {
if ( CACHE.containsKey(n) ) {
return CACHE.get(n);
}
BigInteger catlin = BigInteger.valueOf(2).multiply(BigInteger.valueOf(2*n-1)).multiply(catlin(n-1)).divide(BigInteger.valueOf(n+1));
CACHE.put(n, catlin);
return catlin;
}
}
}

View file

@ -0,0 +1,29 @@
<html><head><title>Catalan</title></head>
<body><pre id='x'></pre><script type="application/javascript">
function disp(x) {
var e = document.createTextNode(x + '\n');
document.getElementById('x').appendChild(e);
}
var fc = [], c2 = [], c3 = [];
function fact(n) { return fc[n] ? fc[n] : fc[n] = (n ? n * fact(n - 1) : 1); }
function cata1(n) { return Math.floor(fact(2 * n) / fact(n + 1) / fact(n) + .5); }
function cata2(n) {
if (n == 0) return 1;
if (!c2[n]) {
var s = 0;
for (var i = 0; i < n; i++) s += cata2(i) * cata2(n - i - 1);
c2[n] = s;
}
return c2[n];
}
function cata3(n) {
if (n == 0) return 1;
return c3[n] ? c3[n] : c3[n] = (4 * n - 2) * cata3(n - 1) / (n + 1);
}
disp(" meth1 meth2 meth3");
for (var i = 0; i <= 15; i++)
disp(i + '\t' + cata1(i) + '\t' + cata2(i) + '\t' + cata3(i));
</script></body></html>

View file

@ -0,0 +1,85 @@
(() => {
"use strict";
// ----------------- CATALAN NUMBERS -----------------
// catalansDefinitionThree :: [Int]
const catalansDefinitionThree = () =>
// An infinite sequence of Catalan numbers.
scanlGen(
c => n => Math.floor(
(2 * c * pred(2 * n)) / succ(n)
)
)(1)(
enumFrom(1)
);
// ---------------------- TEST -----------------------
// main :: IO ()
const main = () =>
take(15)(
catalansDefinitionThree()
);
// --------------------- GENERIC ---------------------
// enumFrom :: Enum a => a -> [a]
const enumFrom = function* (n) {
// An infinite sequence of integers,
// starting with n.
let v = n;
while (true) {
yield v;
v = 1 + v;
}
};
// pred :: Int -> Int
const pred = x =>
x - 1;
// scanlGen :: (b -> a -> b) -> b -> Gen [a] -> [b]
const scanlGen = f =>
// The series of interim values arising
// from a catamorphism over an infinite list.
startValue => function* (gen) {
let
a = startValue,
x = gen.next();
yield a;
while (!x.done) {
a = f(a)(x.value);
yield a;
x = gen.next();
}
};
// succ :: Int -> Int
const succ = x =>
1 + x;
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = n =>
// The first n elements of a list,
// string of characters, or stream.
xs => Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}).flat();
// MAIN ---
return JSON.stringify(main(), null, 2);
})();

View file

@ -0,0 +1,5 @@
def catalan:
if . == 0 then 1
elif . < 0 then error("catalan is not defined on \(.)")
else (2 * (2*. - 1) * ((. - 1) | catalan)) / (. + 1)
end;

View file

@ -0,0 +1 @@
(range(0; 16), 100) as $i | $i | catalan | [$i, .]

View file

@ -0,0 +1,18 @@
$ jq -M -n -c -f Catalan_numbers.jq
[0,1]
[1,1]
[2,2]
[3,5]
[4,14]
[5,42]
[6,132]
[7,429]
[8,1430]
[9,4862]
[10,16796]
[11,58786]
[12,208012]
[13,742900]
[14,2674440]
[15,9694845]
[100,8.96519947090131e+56]

View file

@ -0,0 +1,8 @@
def catalan_series(max):
def _catalan: # state: [n, catalan(n)]
if .[0] > max then empty
else .,
((.[0] + 1) as $n | .[1] as $cp
| [$n, (2 * (2*$n - 1) * $cp) / ($n + 1) ] | _catalan)
end;
[0,1] | _catalan;

View file

@ -0,0 +1 @@
catalan_series(15)

View file

@ -0,0 +1,4 @@
[0,1]
| recurse( if .[0] == 15 then empty
else .[1] as $c | (.[0] + 1) | [ ., (2 * (2*. - 1) * $c) / (. + 1) ]
end )

View file

@ -0,0 +1,4 @@
catalannum(n::Integer) = binomial(2n, n) ÷ (n + 1)
@show catalannum.(1:15)
@show catalannum(big(100))

View file

@ -0,0 +1,3 @@
catalan: {_{*/(x-i)%1+i:!y-1}[2*x;x+1]%x+1}
catalan'!:15
1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440

View file

@ -0,0 +1,53 @@
abstract class Catalan {
abstract operator fun invoke(n: Int) : Double
protected val m = mutableMapOf(0 to 1.0)
}
object CatalanI : Catalan() {
override fun invoke(n: Int): Double {
if (n !in m)
m[n] = Math.round(fact(2 * n) / (fact(n + 1) * fact(n))).toDouble()
return m[n]!!
}
private fun fact(n: Int): Double {
if (n in facts)
return facts[n]!!
val f = n * fact(n -1)
facts[n] = f
return f
}
private val facts = mutableMapOf(0 to 1.0, 1 to 1.0, 2 to 2.0)
}
object CatalanR1 : Catalan() {
override fun invoke(n: Int): Double {
if (n in m)
return m[n]!!
var sum = 0.0
for (i in 0..n - 1)
sum += invoke(i) * invoke(n - 1 - i)
sum = Math.round(sum).toDouble()
m[n] = sum
return sum
}
}
object CatalanR2 : Catalan() {
override fun invoke(n: Int): Double {
if (n !in m)
m[n] = Math.round(2.0 * (2 * (n - 1) + 1) / (n + 1) * invoke(n - 1)).toDouble()
return m[n]!!
}
}
fun main(args: Array<String>) {
val c = arrayOf(CatalanI, CatalanR1, CatalanR2)
for(i in 0..15) {
c.forEach { print("%9d".format(it(i).toLong())) }
println()
}
}

View file

@ -0,0 +1,8 @@
{def catalan1
{def fac {lambda {:n} {* {S.serie 1 :n}}}}
{lambda {:n}
{floor {+ {/ {fac {* 2 :n}} {fac {+ :n 1}} {fac :n}} 0.5}}}}
-> catalan1
{S.map catalan1 {S.serie 1 15}}
-> 1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845

View file

@ -0,0 +1,23 @@
{def catalan2
{def catalan2.sum
{lambda {:n :a :s :i}
{if {= :i :n}
then {A.set! :n :s :a}
else {catalan2.sum :n
:a
{+ :s {* {catalan2.loop :i :a}
{catalan2.loop {- :n :i 1} :a}}}
{+ :i 1}} }}}
{def catalan2.loop
{lambda {:n :a}
{if {= :n 0}
then 1
else {if {W.equal? {A.get :n :a} undefined}
then {A.get :n {catalan2.sum :n :a 0 0}}
else {A.get :n :a} }}}}
{lambda {:n}
{catalan2.loop :n {A.new}} }}
-> catalan2
{S.map catalan2 {S.serie 0 15}}
-> 1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845

View file

@ -0,0 +1,20 @@
{def catalan3
{def catalan3.loop
{lambda {:n :a}
{if {= :n 0}
then 1
else {if {W.equal? {A.get :n :a} undefined}
then {A.get :n
{A.set! :n
{/ {* {- {* 4 :n} 2}
{catalan3.loop {- :n 1} :a}}
{+ :n 1}}
:a}}
else {A.get :n :a}
}}}}
{lambda {:n}
{catalan3.loop :n {A.new}}}}
-> catalan3
{S.map catalan3 {S.serie 0 15}}
-> 1 1 2 5 14 42 132 429 1430 4862 16796 58786 208012 742900 2674440 9694845

View file

@ -0,0 +1,32 @@
{style
td { text-align:right;
font-family:monospace;
}
}
{table
{tr {td} {td cat1} {td cat2} {td cat3}}
{S.map {lambda {:i} {tr {td :i}
{td {catalan1 :i}}
{td {catalan2 :i}}
{td {catalan3 :i}}}}
{S.serie 0 15}}
}
cat1 cat2 cat3
0 1 1 1
1 1 1 1
2 2 2 2
3 5 5 5
4 14 14 14
5 42 42 42
6 132 132 132
7 429 429 429
8 1430 1430 1430
9 4862 4862 4862
10 16796 16796 16796
11 58786 58786 58786
12 208012 208012 208012
13 742900 742900 742900
14 2674440 2674440 2674440
15 9694845 9694845 9694845

View file

@ -0,0 +1,8 @@
val .factorial = f if(.x < 2: 1; .x x self(.x - 1))
val .catalan = f(.n) .factorial(2 x .n) / .factorial(.n+1) / .factorial(.n)
for .i in 0..15 {
writeln $"\.i:2;: \(.catalan(.i):10)"
}
writeln "10000: ", .catalan(10000)

View file

@ -0,0 +1,53 @@
print "non-recursive version"
print catNonRec(5)
for i = 0 to 15
print i;" = "; catNonRec(i)
next
print
print "recursive version"
print catRec(5)
for i = 0 to 15
print i;" = "; catRec(i)
next
print
print "recursive with memoisation"
redim cats(20) 'clear the array
print catRecMemo(5)
for i = 0 to 15
print i;" = "; catRecMemo(i)
next
print
wait
function catNonRec(n) 'non-recursive version
catNonRec=1
for i=1 to n
catNonRec=((2*((2*i)-1))/(i+1))*catNonRec
next
end function
function catRec(n) 'recursive version
if n=0 then
catRec=1
else
catRec=((2*((2*n)-1))/(n+1))*catRec(n-1)
end if
end function
function catRecMemo(n) 'recursive version with memoisation
if n=0 then
catRecMemo=1
else
if cats(n-1)=0 then 'call it recursively only if not already calculated
prev = catRecMemo(n-1)
else
prev = cats(n-1)
end if
catRecMemo=((2*((2*n)-1))/(n+1))*prev
end if
cats(n) = catRecMemo 'memoisation for future use
end function

View file

@ -0,0 +1,11 @@
to factorial :n
output ifelse [less? :n 1] 1 [product :n factorial difference :n 1]
end
to choose :n :r
output quotient factorial :n product factorial :r factorial difference :n :r
end
to catalan :n
output product (quotient sum :n 1) choose product 2 :n :n
end
repeat 15 [print catalan repcount]

View file

@ -0,0 +1,10 @@
:- initialization((
% libraries
logtalk_load(dates(loader)),
logtalk_load(meta(loader)),
logtalk_load(types(loader)),
% application
logtalk_load(seqp),
logtalk_load(catalan),
logtalk_load(catalan_test)
)).

View file

@ -0,0 +1,9 @@
:- protocol(seqp).
:- public(init/0). % reset to a beginning state if meaningful
:- public(nth/2). % get the nth value of the sequence
:- public(to_nth/2). % get from the start to the nth value of the sequence as a list
:- end_protocol.

View file

@ -0,0 +1,28 @@
:- object(catalan, implements(seqp)).
:- private(catalan/2).
:- dynamic(catalan/2).
% Public interface.
init :- retractall(catalan(_,_)). % flush any memoized results
nth(N, V) :- \+ catalan(N, V), catalan_(N, V), !. % generate iff it's not been memoized
nth(N, V) :- catalan(N, V), !. % otherwise use the memoized version
to_nth(N, L) :-
integer::sequence(0, N, S), % generate a list of 0 to N
meta::map(nth, S, L). % map the nth/2 predicate to the list for all Catalan numbers up to N
% Local helper predicates.
catalan_(N, V) :-
N > 0, % calculate
N1 is N - 1,
N2 is N + 1,
catalan_(N1, V1), % via a recursive call
V is V1 * 2 * (2 * N - 1) // N2,
assertz(catalan(N, V)). % and memoize the result
catalan_(0, 1).
:- end_object.

View file

@ -0,0 +1,41 @@
:- object(catalan_test).
:- public(run/0).
run :-
% put the object into a known initial state
catalan::init,
% first 15 Catalan numbers, record duration.
time_operation(catalan::to_nth(15, C1), D1),
% first 15 Catalan numbers again, twice, recording duration.
time_operation(catalan::to_nth(15, C2), D2),
time_operation(catalan::to_nth(15, C3), D3),
% reset the object again
catalan::init,
% first 15 Catalan numbers, record duration.
time_operation(catalan::to_nth(15, C4), D4),
% ensure the results were the same each time
C1 = C2, C2 = C3, C3 = C4,
% write the results and durations of each run
write(C1), write(' '), write(D1), nl,
write(C2), write(' '), write(D2), nl,
write(C3), write(' '), write(D3), nl,
write(C4), write(' '), write(D4), nl.
% visual inspection should show all results the same
% first and final durations should be much larger
:- meta_predicate(time_operation(0, *)).
time_operation(Goal, Duration) :-
time::cpu_time(Before),
call(Goal),
time::cpu_time(After),
Duration is After - Before.
:- end_object.

View file

@ -0,0 +1,12 @@
-- recursive with memoization
local catalan = { [0] = 1 }
setmetatable(catalan, {
__index = function(c, n)
c[n] = c[n - 1] * 2 * (2 * n - 1) / (n + 1)
return c[n]
end
})
for i = 0, 14 do
print(string.format("%d", catalan[i]))
end

View file

@ -0,0 +1,12 @@
NORMAL MODE IS INTEGER
DIMENSION C(15)
C(0) = 1
THROUGH CALC, FOR N=1, 1, N.GE.15
CALC C(N) = ((4*N-2)*C(N-1))/(N+1)
THROUGH SHOW, FOR N=0, 1, N.GE.15
SHOW PRINT FORMAT CFMT,N,C(N)
VECTOR VALUES CFMT=$2HC(,I2,4H) = ,I7*$
END OF PROGRAM

View file

@ -0,0 +1,5 @@
function n = catalanNumber(n)
for i = (1:length(n))
n(i) = (1/(n(i)+1))*nchoosek(2*n(i),n(i));
end
end

View file

@ -0,0 +1,3 @@
function n = catalanNumbers(n)
n = [1 cumprod((2:4:4*n-6) ./ (2:n))];
end

View file

@ -0,0 +1,28 @@
>> catalanNumber(14)
ans =
2674440
>> catalanNumbers(18)'
ans =
1
1
2
5
14
42
132
429
1430
4862
16796
58786
208012
742900
2674440
9694845
35357670
129644790

View file

@ -0,0 +1 @@
CatalanNumber=@(n) round(exp(gammaln(2*n+1)-sum(gammaln([n+2 n+1]))));

View file

@ -0,0 +1,11 @@
>>CatalanNumber(10)
ans =
16796
>> num2str(CatalanNumber(20))
ans =
'6564120420'

View file

@ -0,0 +1,4 @@
CatalanNumbers := proc( n::posint )
return seq( (2*i)!/((i + 1)!*i!), i = 0 .. n - 1 );
end proc:
CatalanNumbers(15);

View file

@ -0,0 +1 @@
CatalanN[n_Integer /; n >= 0] := (2 n)!/((n + 1)! n!)

View file

@ -0,0 +1,18 @@
TableForm[CatalanN/@Range[0,15]]
//TableForm=
1
1
2
5
14
42
132
429
1430
4862
16796
58786
208012
742900
2674440
9694845

View file

@ -0,0 +1,11 @@
/* The following is an array function, hence the square brackets. It uses memoization automatically */
cata[n] := sum(cata[i]*cata[n - 1 - i], i, 0, n - 1)$
cata[0]: 1$
cata2(n) := binomial(2*n, n)/(n + 1)$
makelist(cata[n], n, 0, 14);
makelist(cata2(n), n, 0, 14);
/* both return [1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440] */

View file

@ -0,0 +1,12 @@
10 REM Catalan numbers
20 DIM C(15)
30 LET C(0) = 1
40 PRINT 0, C(0)
50 FOR N = 0 TO 14
60 LET C(N+1) = 0
70 FOR I = 0 TO N
80 LET C(N+1) = C(N+1)+C(I)*C(N-I)
90 NEXT I
100 PRINT N+1, C(N+1)
110 NEXT N
120 END

View file

@ -0,0 +1,6 @@
main :: [sys_message]
main = [Stdout (lay (map (show . catalan) [0..14]))]
catalan :: num->num
catalan 0 = 1
catalan n = (4*n - 2) * catalan (n - 1) div (n + 1)

Some files were not shown because too many files have changed in this diff Show more