2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -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]] 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>
|
||||
|
|
|
|||
32
Task/Catalan-numbers/ALGOL-68/catalan-numbers.alg
Normal file
32
Task/Catalan-numbers/ALGOL-68/catalan-numbers.alg
Normal 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
|
||||
1
Task/Catalan-numbers/APL/catalan-numbers.apl
Normal file
1
Task/Catalan-numbers/APL/catalan-numbers.apl
Normal file
|
|
@ -0,0 +1 @@
|
|||
{(!2×⍵)÷(!⍵+1)×!⍵}(⍳15)-1
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
55
Task/Catalan-numbers/Kotlin/catalan-numbers.kotlin
Normal file
55
Task/Catalan-numbers/Kotlin/catalan-numbers.kotlin
Normal 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()
|
||||
}
|
||||
}
|
||||
10
Task/Catalan-numbers/PowerShell/catalan-numbers-1.psh
Normal file
10
Task/Catalan-numbers/PowerShell/catalan-numbers-1.psh
Normal 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 $_)"}
|
||||
51
Task/Catalan-numbers/PowerShell/catalan-numbers-2.psh
Normal file
51
Task/Catalan-numbers/PowerShell/catalan-numbers-2.psh
Normal 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Task/Catalan-numbers/PowerShell/catalan-numbers-3.psh
Normal file
1
Task/Catalan-numbers/PowerShell/catalan-numbers-3.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
0..14 | Get-CatalanNumber
|
||||
1
Task/Catalan-numbers/PowerShell/catalan-numbers-4.psh
Normal file
1
Task/Catalan-numbers/PowerShell/catalan-numbers-4.psh
Normal file
|
|
@ -0,0 +1 @@
|
|||
(0..14 | Get-CatalanNumber).CatalanNumber
|
||||
|
|
@ -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.*/
|
||||
|
|
|
|||
12
Task/Catalan-numbers/ZX-Spectrum-Basic/catalan-numbers.zx
Normal file
12
Task/Catalan-numbers/ZX-Spectrum-Basic/catalan-numbers.zx
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue