Skip to content

Commit 5fc9818

Browse files
committed
add catalan numbers implementation
1 parent b7907e8 commit 5fc9818

File tree

4 files changed

+141
-0
lines changed

4 files changed

+141
-0
lines changed

math/catalan/catalan.mbt

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
///|
2+
struct Catalan {
3+
values : Array[Int64]
4+
}
5+
6+
///|
7+
/// Construct a Catalan number table up to `max_n`.
8+
///
9+
/// # Parameters
10+
/// - `max_n`: the maximum index that should be precomputed. Must be non-negative.
11+
///
12+
/// # Returns
13+
/// - `Catalan`: a table containing Catalan numbers from `C_0` to `C_{max_n}`.
14+
///
15+
/// # Example
16+
/// ```
17+
/// let catalan = Catalan::new(5)
18+
/// inspect(catalan.nth(4), content="14")
19+
/// ```
20+
pub fn Catalan::new(max_n : Int) -> Catalan {
21+
if max_n < 0 {
22+
abort("max_n must be non-negative")
23+
}
24+
let size = max_n + 1
25+
let values = Array::make(size, 0L)
26+
values[0] = 1L
27+
for n in 1..<size {
28+
let mut sum : Int64 = 0L
29+
for left in 0..<n {
30+
sum = sum + values[left] * values[n - 1 - left]
31+
}
32+
values[n] = sum
33+
}
34+
Catalan::{ values, }
35+
}
36+
37+
///|
38+
/// Get the `n`-th Catalan number from the precomputed table.
39+
///
40+
/// # Parameters
41+
/// - `self`: precomputed Catalan table.
42+
/// - `n`: the index of the Catalan number.
43+
///
44+
/// # Returns
45+
/// - `Int64`: the value `C_n`.
46+
///
47+
/// # Example
48+
/// ```
49+
/// let catalan = Catalan::new(10)
50+
/// inspect(catalan.nth(10), content="16796")
51+
/// ```
52+
pub fn nth(self : Catalan, n : Int) -> Int64 {
53+
if n < 0 || n >= self.values.length() {
54+
abort("n is out of precomputed range")
55+
}
56+
self.values[n]
57+
}
58+
59+
///|
60+
/// Retrieve all precomputed Catalan numbers as an array.
61+
///
62+
/// # Parameters
63+
/// - `self`: precomputed Catalan table.
64+
///
65+
/// # Returns
66+
/// - `Array[Int64]`: Catalan numbers from `C_0` to `C_max`.
67+
///
68+
/// # Example
69+
/// ```
70+
/// let catalan = Catalan::new(4)
71+
/// inspect(catalan.values(), content="[1, 1, 2, 5, 14]")
72+
/// ```
73+
pub fn values(self : Catalan) -> Array[Int64] {
74+
self.values
75+
}
76+
77+
///|
78+
/// Compute the `n`-th Catalan number on demand.
79+
///
80+
/// # Parameters
81+
/// - `n`: the desired index. Must be non-negative.
82+
///
83+
/// # Returns
84+
/// - `Int64`: the value `C_n`.
85+
///
86+
/// # Example
87+
/// ```
88+
/// inspect(catalan_number(3), content="5")
89+
/// ```
90+
pub fn catalan_number(n : Int) -> Int64 {
91+
Catalan::new(n).nth(n)
92+
}

math/catalan/catalan_test.mbt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
///|
2+
test "sequence prefix" {
3+
let catalan = Catalan::new(15)
4+
inspect(
5+
catalan.values(),
6+
content="[1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845]",
7+
)
8+
}
9+
10+
///|
11+
test "on demand computation" {
12+
inspect(catalan_number(0), content="1")
13+
inspect(catalan_number(1), content="1")
14+
inspect(catalan_number(2), content="2")
15+
inspect(catalan_number(3), content="5")
16+
inspect(catalan_number(7), content="429")
17+
inspect(catalan_number(10), content="16796")
18+
}
19+
20+
///|
21+
test "recurrence and large values" {
22+
let catalan = Catalan::new(35)
23+
let mut convolution : Int64 = 0L
24+
for left in 0..<6 {
25+
convolution = convolution + catalan.nth(left) * catalan.nth(5 - left)
26+
}
27+
inspect(convolution, content="132")
28+
inspect(catalan.nth(20), content="6564120420")
29+
inspect(catalan.nth(35), content="3116285494907301262")
30+
}

math/catalan/moon.pkg.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ }

math/catalan/pkg.generated.mbti

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Generated using `moon info`, DON'T EDIT IT
2+
package "Lampese/Algorithms-Moonbit/math/catalan"
3+
4+
// Values
5+
fn catalan_number(Int) -> Int64
6+
7+
// Errors
8+
9+
// Types and methods
10+
type Catalan
11+
fn Catalan::new(Int) -> Self
12+
fn Catalan::nth(Self, Int) -> Int64
13+
fn Catalan::values(Self) -> Array[Int64]
14+
15+
// Type aliases
16+
17+
// Traits
18+

0 commit comments

Comments
 (0)