-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathp66.re
46 lines (45 loc) · 1.32 KB
/
p66.re
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
/* Layout a binary tree (another). */
type binary_tree('a) =
| Leaf
| Node('a, binary_tree('a), binary_tree('a));
let layout_binary_tree_3 = {
let rec translate_x = (d, tree) =>
switch tree {
| Leaf => Leaf
| Node((v, x, y), l, r) => Node((v, x + d, y), translate_x(d, l), translate_x(d, r))
};
let rec dist = (lr, rl) =>
switch (lr, rl) {
| ([lrx, ...ltl], [rlx, ...rtl]) => max(lrx - rlx, dist(ltl, rtl))
| ([], _)
| (_, []) => 0
};
let rec merge_profiles = (p1, p2) =>
switch (p1, p2) {
| ([x1, ...tl1], [_, ...tl2]) => [x1, ...merge_profiles(tl1, tl2)]
| ([], _) => p2
| (_, []) => p1
};
let rec layout = (depth, tree) =>
switch tree {
| Leaf => ([], Leaf, [])
| Node(v, l, r) =>
let (ll, l', lr) = layout(depth + 1, l);
let (rl, r', rr) = layout(depth + 1, r);
let d = 1 + dist(lr, rl) / 2;
let ll = List.map((x) => x - d, ll)
and lr = List.map((x) => x - d, lr)
and rl = List.map((+)(d), rl)
and rr = List.map((+)(d), rr);
(
[0, ...merge_profiles(ll, rl)],
Node((v, 0, depth), translate_x(- d, l'), translate_x(d, r')),
[0, ...merge_profiles(rr, lr)]
)
};
(t) => {
let (l, t', _) = layout(1, t);
let x_min = List.fold_left(min, 0, l);
translate_x(1 - x_min, t')
}
};