data (Eq a, Show a) => QT a = C a | Q (QT a) (QT a) (QT a) (QT a)
deriving (Eq, Show)
Giving the definition as above, write a predicate to check if a given image (coded as a quadtree) is symmetric in respect of vertical axis (horizontal symmetric). Use anonymous function where possible.
Question: How would you implement horizontal symmetry check for a given quadtree?
Well, I was thinking at something like this: when a quadtree is just a leaf, in that case we have horizontal symmetry. Base case is when quadtree has just one level (four leafs) symmetry is just a matter of checking the colors (c1 == c2 && c3 == c4)
.
In any other case, I might check if this condition is recursive satisfied: nw equals (fliphorizontal(ne)) && sw equals (fliphorizontal(se))
, where fliphorizontal
flips the quadtree horizontally and equals
checks if two quadtrees are equal. However I would like to avoid the use of external function as possible, just anonymous ones if possible.
ishsymmetric :: (Eq a, Show a) => QT a -> Bool
ishsymmetric (C _) = True
ishsymmetric (Q (C c1) (C c2) (C c3) (C c4)) = c1 == c2 && c3 == c4
ishsymmetric (Q nw ne sw se) =
EDIT: fliph example:
fliph :: (Eq a, Show a) => QT a -> QT a
fliph (C a) = C a
fliph (Q nw ne sw se) = Q (fliph ne) (fliph nw) (fliph se) (fliph sw)
EDIT: final one-function solution (using generalized fold function for quadtrees):
ishsymmetric :: (Eq a, Show a) => QT a -> Bool
ishsymmetric (C _) = True
ishsymmetric (Q a b c d) = and $ zipWith equals [a,c] [fliph b,fliph d]
where
fold f g (C c) = g c
fold f g (Q a b c d) = f (fold f g a) (fold f g b)
(fold f g c) (fold f g d)
fliph q = fold (\a b c d -> Q b a d c) (\c -> C c) q
equals (C c1) (C c2) = c1 == c2
equals (Q a b c d) (Q e f g h) = and $ zipWith equals [a,b,c,d] [e,f,g,h]
Something like:
But syntactic optimizations are possible. :-/