2016 Update

This commit is contained in:
Tina Müller 2016-12-05 22:15:40 +01:00
parent 948b86eafa
commit dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions

View file

@ -1,3 +1,4 @@
<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:
@ -5,8 +6,14 @@ Or recursively:
Or alternatively (also recursive):
:<math>C_0 = 1 \quad \mbox{and} \quad C_n=\frac{2(2n-1)}{n+1}C_{n-1},</math>
Implement at least one of these algorithms and print out the first 15 Catalan numbers with each. [[Memoization]] is not required, but may be worth the effort when using the second method above.
Related tasks:
;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,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 @@
{(!2×)÷(!+1)×!}(15)-1

View file

@ -11,7 +11,7 @@ feature {NONE}
across
0 |..| 14 as c
loop
io.put_double (catalan_numbers (c.item))
io.put_double (nth_catalan_number (c.item))
io.new_line
end
end
@ -28,7 +28,7 @@ feature {NONE}
else
t := 4 * n.to_double - 2
s := n.to_double + 1
Result := t / s * catalan_numbers (n - 1)
Result := t / s * nth_catalan_number (n - 1)
end
end

View file

@ -0,0 +1,55 @@
import net.openhft.koloboke.collect.map.hash.HashIntDoubleMaps.*
abstract class Catalan {
abstract operator fun invoke(n: Int) : Double
protected val m = newUpdatableMapOf(0 , 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]
var f = n * fact(n -1)
facts[n] = f
return f
}
private val facts = newUpdatableMapOf(0 , 1.0, 1 , 1.0, 2 , 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,10 @@
function Catalan([uint64]$m) {
function fact([bigint]$n) {
if($n -lt 2) {[bigint]::one}
else{2..$n | foreach -Begin {$prod = [bigint]::one} -Process {$prod = [bigint]::Multiply($prod,$_)} -End {$prod}}
}
$fact = fact $m
$fact1 = [bigint]::Multiply($m+1,$fact)
[bigint]::divide((fact (2*$m)), [bigint]::Multiply($fact,$fact1))
}
0..15 | foreach {"catalan($_): $(catalan $_)"}

View file

@ -0,0 +1,51 @@
function Get-CatalanNumber
{
[CmdletBinding()]
[OutputType([PSCustomObject])]
Param
(
[Parameter(Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true,
Position=0)]
[uint32[]]
$InputObject
)
Begin
{
function Get-Factorial ([int]$Number)
{
if ($Number -eq 0)
{
return 1
}
$factorial = 1
1..$Number | ForEach-Object {$factorial *= $_}
$factorial
}
function Get-Catalan ([int]$Number)
{
if ($Number -eq 0)
{
return 1
}
(Get-Factorial (2 * $Number)) / ((Get-Factorial (1 + $Number)) * (Get-Factorial $Number))
}
}
Process
{
foreach ($number in $InputObject)
{
[PSCustomObject]@{
Number = $number
CatalanNumber = Get-Catalan $number
}
}
}
}

View file

@ -0,0 +1 @@
0..14 | Get-CatalanNumber

View file

@ -0,0 +1 @@
(0..14 | Get-CatalanNumber).CatalanNumber

View file

@ -1,31 +1,23 @@
/*REXX program calculates Catalan numbers using four different methods. */
parse arg bot top . /*get optional arguments from the C.L. */
if bot=='' then do; top=15; bot=0; end /*No args? Use a range of 0 ───► 15. */
if top=='' then top=bot /*No top? Use the bottom for default. */
numeric digits max(20, 5*top) /*this allows gihugic Catalan numbers. */
@cat=' Catalan' /*a nice literal to have for the SAY. */
w=length(top) /*width of the largest number for SAY. */
call hdr 1A; do j=bot to top; say @cat right(j,w)": " Catalan1A(j); end
call hdr 1B; do j=bot to top; say @cat right(j,w)": " Catalan1B(j); end
call hdr 2 ; do j=bot to top; say @cat right(j,w)": " Catalan2(j); end
call hdr 3 ; do j=bot to top; say @cat right(j,w)": " Catalan3(j); end
exit /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
Catalan1A: procedure expose !.; parse arg n; return comb(n+n, n) % (n+1)
Catalan1B: procedure expose !.; parse arg n; return !(n+n) % ((n+1) * !(n)**2)
comb: procedure; parse arg x,y; return pFact(x-y+1,x) % pFact(2,y)
pFact: procedure; !=1; do k=arg(1) to arg(2); !=!*k; end; return !
/*────────────────────────────────────────────────────────────────────────────*/
hdr: !.=.; c.=.; c.0=1; say
say center(' Catalan numbers, method' left(arg(1),3), 79, ''); return
/*────────────────────────────────────────────────────────────────────────────*/
!: procedure expose !.; parse arg x; !=1; if !.x\==. then return !.x
do k=1 for x; !=!*k; end /*k*/
!.x=!; return !
/*──────────────────────────────────Catalan method 2──────────────────────────*/
Catalan2: procedure expose c.; parse arg n; $=0; if c.n\==. then return c.n
do k=0 to n-1; $=$+catalan2(k)*catalan2(n-k-1); end
c.n=$; return $ /*use a REXX memoization technique. */
/*──────────────────────────────────Catalan method 3──────────────────────────*/
Catalan3: procedure expose c.; parse arg n
if c.n==. then c.n=(4*n-2) * catalan3(n-1) % (n+1); return c.n
/*REXX program calculates and displays Catalan numbers using four different methods. */
parse arg LO HI . /*obtain optional arguments from the CL*/
if LO=='' | LO=="," then do; HI=15; LO=0; end /*No args? Then use a range of 0 ──► 15*/
if HI=='' | HI=="," then HI=LO /*No HI? Then use LO for the default*/
numeric digits max(20, 5*HI) /*this allows gihugic Catalan numbers. */
w=length(HI) /*W: is used for aligning the output. */
call hdr 1A; do j=LO to HI; say ' Catalan' right(j, w)": " Cat1A(j); end
call hdr 1B; do j=LO to HI; say ' Catalan' right(j, w)": " Cat1B(j); end
call hdr 2 ; do j=LO to HI; say ' Catalan' right(j, w)": " Cat2(j) ; end
call hdr 3 ; do j=LO to HI; say ' Catalan' right(j, w)": " Cat3(j) ; end
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
!: arg z; if !.z\==. then return !.z; !=1; do k=2 for z; !=!*k; end; !.z=!; return !
Cat1A: procedure expose !.; parse arg n; return comb(n+n, n) % (n+1)
Cat1B: procedure expose !.; parse arg n; return !(n+n) % ((n+1) * !(n)**2)
Cat3: procedure expose c.; arg n; if c.n==. then c.n=(4*n-2)*cat3(n-1)%(n+1); return c.n
comb: procedure; parse arg x,y; return pFact(x-y+1, x) % pFact(2, y)
hdr: !.=.; c.=.; c.0=1; say; say center('Catalan numbers, method' arg(1),79,''); return
pFact: procedure; !=1; do k=arg(1) to arg(2); !=!*k; end; return !
/*──────────────────────────────────────────────────────────────────────────────────────*/
Cat2: procedure expose c.; parse arg n; $=0; if c.n\==. then return c.n
do k=0 to n-1; $=$ + cat2(k) * cat2(n-k-1); end
c.n=$; return $ /*use a memoization technique.*/

View file

@ -0,0 +1,12 @@
10 FOR i=0 TO 15
20 LET n=i: LET m=2*n
30 LET r=1: LET d=m-n
40 IF d>n THEN LET n=d: LET d=m-n
50 IF m<=n THEN GO TO 90
60 LET r=r*m: LET m=m-1
70 IF (d>1) AND NOT FN m(r,d) THEN LET r=r/d: LET d=d-1: GO TO 70
80 GO TO 50
90 PRINT i;TAB 4;r/(1+n)
100 NEXT i
110 STOP
120 DEF FN m(a,b)=a-INT (a/b)*b: REM Modulus function