99-haskell-problems/Problems 54A-60/problem_60.hs

37 lines
1.1 KiB
Haskell

data Tree a = Empty | Branch a (Tree a) (Tree a)
deriving (Show, Eq)
maxNodes :: Int -> Int
maxNodes = subtract 1 . (2 ^)
minNodesSeq :: [Int]
minNodesSeq = 0 : 1 : zipWith ((+) . (1 +)) minNodesSeq (tail minNodesSeq)
minNodes :: Int -> Int
minNodes = (!!) minNodesSeq
maxHeight :: Int -> Int
maxHeight n = subtract 1 $ length $ takeWhile (<= n) minNodesSeq
minHeight :: Int -> Int
minHeight = ceiling . logBase 2 . fromIntegral . (+ 1)
countNodes :: Tree a -> Int
countNodes Empty = 0
countNodes (Branch _ l r) = countNodes l + countNodes r + 1
hbalTree :: a -> Int -> [Tree a]
hbalTree _ 0 = [Empty]
hbalTree x 1 = [Branch x Empty Empty]
hbalTree x n =
[Branch x l r | l <- minustwocase, r <- minusonecase]
++ [Branch x l r | l <- minusonecase, r <- minusonecase]
++ [Branch x l r | l <- minusonecase, r <- minustwocase]
where
minusonecase = hbalTree x (n - 1)
minustwocase = hbalTree x (n - 2)
hbalTreeNodes :: a -> Int -> [Tree a]
hbalTreeNodes _ 0 = [Empty]
hbalTreeNodes x n = concatMap (filter ((n ==) . countNodes) . hbalTree x) [minHeight n .. maxHeight n]