Problem 64 Solutions

Solution 1

Set the x and y coordinates in a single pass using in-order traversal.

layout : Tree a -> Tree (a, (Int, Int))
layout tree =
    layoutAux 1 1 tree 
      |> Tuple.first

layoutAux : Int -> Int -> Tree a -> (Tree (a,(Int,Int)), Int)
layoutAux x y tree =
    case tree of 
        Empty -> 
            (Empty, x)

        Node n l r ->
            let
                (lTree, xl) = layoutAux x (y+1) l
                (rTree, xr) = layoutAux (xl+1) (y+1) r
            in
                (Node (n, (xl,y)) lTree rTree, xr)

Solution 2

This solution breaks down the process into three steps,

  • Inserting a coordinate to each node
treeMap addXY tree
  • Setting the y value to the depth
treeMapDepth setY 1
  • Setting the x value to the in-order index
treeMapInOrder setX 1

This is not an efficient solution, as the tree must be traversed multiple times. However the traversal functions treeMapDepth and treeMapInOrder modeled on List.indexedMap will be useful functions for other problems.

layout : Tree a -> Tree (a, (Int, Int))
layout tree =
    treeMap addXY tree
      |> treeMapDepth setY 1
      |> treeMapInOrder setX 1


addXY : a -> (a, (Int, Int))
addXY v =
    (v, (0, 0))


setY : Int -> (a, (Int, Int)) -> (a, (Int, Int))
setY n (v, (x, y)) =
    (v, (x, n))


setX : Int -> (a, (Int, Int)) -> (a, (Int, Int))
setX n (v, (x, y)) =
    (v, (n, y))


treeMap : (a -> b) -> Tree a -> Tree b
treeMap f tree =   
    case tree of 
        Empty -> 
            Empty

        Node v left right ->
            Node (f v) (treeMap f left) (treeMap f right)


-- apply a function to each node, passing the depth as a parameter
treeMapDepth : (Int -> a -> b) -> Int -> Tree a -> Tree b
treeMapDepth f d tree =   
    case tree of 
        Empty -> 
            Empty

        Node v left right ->
            Node (f d v) 
                (treeMapDepth f (d + 1) left) 
                (treeMapDepth f (d + 1) right)



-- apply a function to each node, passing the in-order index as a parameter
treeMapInOrder : (Int -> a -> b) -> Int -> Tree a -> Tree b
treeMapInOrder f n tree =   
    case tree of 
        Empty -> 
            Empty

        Node v left right ->
            let 
                nn = (n + (treeCount left))
            in 
                Node  (f nn v) 
                    (treeMapInOrder f n left)
                    (treeMapInOrder f (nn + 1) right)


-- count number of Nodes in a Tree    
treeCount : Tree a -> Int
treeCount tree = 
    case tree of 
        Empty -> 0

        Node n left right ->
            1 + (treeCount left) + (treeCount right)

Back to problem

results matching ""

    No results matching ""