--Problem 60: Construct height-balanced binary trees with a given number of nodes.
heightBalTreeNodes :: a -> Int -> [Tree a]
heightBalTreeNodes x n = concatMap filterToTrees [minHeight .. maxHeight] where
    --filterToTrees :: Int -> [Tree a]
    filterToTrees = filter ((n ==) . countNodes) . heightBalTree x
    minNodesSequence :: [Int]
    minNodesSequence = 0 : 1 : zipWith ((+) . (1 +)) minNodesSequence (tail minNodesSequence)
    minHeight :: Int
    minHeight = ceiling $ logBase 2 $ fromIntegral $ n + 1
    maxHeight :: Int
    maxHeight = fromJust (findIndex (> n) minNodesSequence) - 1
    countNodes :: Tree a -> Int
    countNodes Empty = 0
    countNodes (Branch _ l r) = countNodes l + countNodes r + 1
heightBalTreeNodes :: a -> Int -> [Tree a]
heightBalTreeNodes x n = concatMap filterToTrees [minHeight .. maxHeight] where
    --filterToTrees :: Int -> [Tree a]
    filterToTrees = filter ((n ==) . countNodes) . heightBalTree x
    minNodesSequence :: [Int]
    minNodesSequence = 0 : 1 : zipWith ((+) . (1 +)) minNodesSequence (tail minNodesSequence)
    minHeight :: Int
    minHeight = ceiling $ logBase 2 $ fromIntegral $ n + 1
    maxHeight :: Int
    maxHeight = fromJust (findIndex (> n) minNodesSequence) - 1
    countNodes :: Tree a -> Int
    countNodes Empty = 0
    countNodes (Branch _ l r) = countNodes l + countNodes r + 1
heightBalTreeNodes x n = concatMap filterToTrees [minHeight .. maxHeight] where
    --filterToTrees :: Int -> [Tree a]
    filterToTrees = filter ((n ==) . countNodes) . heightBalTree x
    minNodesSequence :: [Int]
    minNodesSequence = 0 : 1 : zipWith ((+) . (1 +)) minNodesSequence (tail minNodesSequence)
    minHeight :: Int
    minHeight = ceiling $ logBase 2 $ fromIntegral $ n + 1
    maxHeight :: Int
    maxHeight = fromJust (findIndex (> n) minNodesSequence) - 1
    countNodes :: Tree a -> Int
    countNodes Empty = 0
    countNodes (Branch _ l r) = countNodes l + countNodes r + 1