1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use std::{iter::once, rc::Rc};
pub struct Tree {
node: Node,
}
pub enum Node {
Leaf,
Branch {
left: Rc<Tree>,
right: Box<Tree>,
},
}
impl Tree {
pub fn apply<T>(
&self,
functions: &mut impl Iterator<Item = impl FnOnce(T, T) -> T>,
values: &mut impl Iterator<Item = T>,
) -> Option<T> {
match &self.node {
Node::Leaf => values.next(),
Node::Branch { left, right } => {
Some(functions.next()?(left.apply(functions, values)?, right.apply(functions, values)?))
}
}
}
}
pub fn catalan_trees(rank: usize) -> Box<dyn Iterator<Item = Tree>> {
assert!(rank > 0);
if rank == 1 {
box once(Tree { node: Node::Leaf })
}
else {
box (1..=rank - 1).flat_map(move |left_rank| {
let right_rank = rank - left_rank;
catalan_trees(left_rank).map(Rc::new).flat_map(move |left| {
catalan_trees(right_rank)
.map(Box::new)
.map(move |right| Tree { node: Node::Branch { left: left.clone(), right } })
})
})
}
}