-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathP55.hs
More file actions
49 lines (45 loc) · 1.69 KB
/
P55.hs
File metadata and controls
49 lines (45 loc) · 1.69 KB
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
module BinaryTree.P55 (cbalTree) where
import BinaryTree.BinaryTree (Tree (..))
{-
Problem 55: (**) Construct completely balanced binary trees.
In a completely balanced binary tree, the following property holds for every node:
The number of nodes in its left subtree and the number of nodes in its right subtree
are almost equal, which means their difference is not greater than one.
-}
cbalTree :: Int -> [Tree Char]
cbalTree = map fst . build
where
build :: Int -> [(Tree Char, Int)]
build n
| n == 0 = []
| n == 1 = [(singleton 'x', 1)]
| n == 2 =
[ (Branch 'x' (singleton 'x') Empty, 2),
(Branch 'x' Empty (singleton 'x'), 2)
]
| otherwise = do
let k = (n - 1) `div` 2
{-
We can take the cartesian product of 2 lists
in a variety of ways.
1. Monad -- liftM2 (,)
2. sequence -- generates a list of lists
3. Applicative -- (,) <$> xs <*> ys
4. List comprehension -- [(x, y) | x <- xs, y <- yy]
5. do notation
6. Bind -- xs >>= (\x -> ys >>= (\y -> (x, y)))
7. Bind pointfree (ys >>=) . (,) =<< xs
8. Using MonadPlus -- xs `mplus` ys
-}
(l, i) <- build k
(r, j) <- build (n - k - 1)
let x = i + j + 1
{-
Create new trees combining the left and right subtrees.
If they have the same height, then swapping them produces
the same tree, so, we check in order to avoid generating
duplicates.
-}
(Branch 'x' l r, x) : [(Branch 'x' r l, x) | abs (i - j) == 1]
singleton :: a -> Tree a
singleton x = Branch x Empty Empty