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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use rand::Rng;
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
enum TreeGenMode {
Perfect(usize),
Full,
FullRanged(usize),
}
#[derive(PartialEq, Eq, Debug)]
pub struct TreeGen<'a, R>
where R: 'a + Rng
{
mode: TreeGenMode,
rng: &'a mut R,
min_depth: usize,
max_depth: usize,
}
impl<'a, R> TreeGen<'a, R>
where R: 'a + Rng
{
pub fn perfect(rng: &mut R, min_depth: usize, max_depth: usize) -> TreeGen<R> {
let chosen_depth = rng.gen_range(min_depth, max_depth + 1);
TreeGen {
rng: rng,
mode: TreeGenMode::Perfect(chosen_depth),
min_depth: min_depth,
max_depth: max_depth,
}
}
pub fn full(rng: &mut R, min_depth: usize, max_depth: usize) -> TreeGen<R> {
TreeGen {
rng: rng,
mode: TreeGenMode::Full,
min_depth: min_depth,
max_depth: max_depth,
}
}
pub fn full_ranged(rng: &mut R, min_depth: usize, max_depth: usize) -> TreeGen<R> {
let chosen_depth = rng.gen_range(min_depth, max_depth + 1);
TreeGen {
rng: rng,
mode: TreeGenMode::FullRanged(chosen_depth),
min_depth: min_depth,
max_depth: max_depth,
}
}
pub fn half_and_half(rng: &mut R, min_depth: usize, max_depth: usize) -> TreeGen<R> {
if rng.gen() {
Self::perfect(rng, min_depth, max_depth)
} else {
Self::full_ranged(rng, min_depth, max_depth)
}
}
pub fn have_reached_a_leaf(&mut self, current_depth: usize) -> bool {
match self.mode {
TreeGenMode::Perfect(chosen_depth) => current_depth == chosen_depth,
TreeGenMode::Full => {
let depth_interval = self.max_depth - self.min_depth;
current_depth == self.max_depth ||
(current_depth >= self.min_depth) && self.gen_weighted_bool(depth_interval as u32)
}
TreeGenMode::FullRanged(chosen_depth) => {
let depth_interval = chosen_depth - self.min_depth;
current_depth == chosen_depth ||
(current_depth >= self.min_depth) && self.gen_weighted_bool(depth_interval as u32)
}
}
}
}
impl<'a, R> Rng for TreeGen<'a, R>
where R: 'a + Rng
{
fn next_u32(&mut self) -> u32 {
self.rng.next_u32()
}
fn next_u64(&mut self) -> u64 {
self.rng.next_u64()
}
fn fill_bytes(&mut self, dest: &mut [u8]) {
self.rng.fill_bytes(dest)
}
}