commit 739ea0d1add7ffb25b3ce8a71cc9e3c8f506feca Author: Danila Fedorin Date: Fri Jan 11 21:17:12 2019 -0800 Add solutions to homework 1. diff --git a/HW1.fedorind.hs b/HW1.fedorind.hs new file mode 100644 index 0000000..4e52e8c --- /dev/null +++ b/HW1.fedorind.hs @@ -0,0 +1,217 @@ +-- Author: Danila Fedorin, Thursday, January 10 +module HW1 where + + +-- | Integer-labeled binary trees. +data Tree + = Node Int Tree Tree -- ^ Internal nodes + | Leaf Int -- ^ Leaf nodes + deriving (Eq,Show) + +-- | An example binary tree, which will be used in tests. +t1 :: Tree +t1 = Node 1 (Node 2 (Node 3 (Leaf 4) (Leaf 5)) + (Leaf 6)) + (Node 7 (Leaf 8) (Leaf 9)) + +-- | Another example binary tree, used in tests. +t2 :: Tree +t2 = Node 6 (Node 2 (Leaf 1) (Node 4 (Leaf 3) (Leaf 5))) + (Node 8 (Leaf 7) (Leaf 9)) + +-- | Right associative fold. +-- The best way here would be to add a foldable instance for Tree. +-- however, since Tree doesn't take a type parameter, this is not possible. +-- We settle for these functions. +treeFoldr :: (Int -> a -> a) -> a -> Tree -> a +treeFoldr f a (Leaf i) = f i a +treeFoldr f a (Node i l r) = treeFoldr f (f i (treeFoldr f a r)) l + +-- | foldr for non-empty lists. +treeFoldr1 :: (Int -> Int -> Int) -> Tree -> Int +treeFoldr1 f (Leaf i) = i +treeFoldr1 f (Node i l r) = treeFoldr f (f i (treeFoldr1 f r)) l + +-- | Left associative fold. +treeFoldl :: (Int -> a -> a) -> a -> Tree -> a +treeFoldl f a (Leaf i) = f i a +treeFoldl f a (Node i l r) = treeFoldl f (f i (treeFoldl f a l)) r + +-- | foldl for non-empty lists. +treeFoldl1 :: (Int -> Int -> Int) -> Tree -> Int +treeFoldl1 f (Leaf i) = i +treeFoldl1 f (Node i l r) = treeFoldl f (f i (treeFoldl1 f l)) r + +-- | In-order traversal fold. +treeFold :: (Int -> a -> a) -> a -> Tree -> a +treeFold f a (Leaf i) = f i a +treeFold f a (Node i l r) = f i $ treeFold f (treeFold f a r) l + +-- | The integer at the left-most node of a binary tree. +-- +-- >>> leftmost (Leaf 3) +-- 3 +-- +-- >>> leftmost (Node 5 (Leaf 6) (Leaf 7)) +-- 6 +-- +-- >>> leftmost t1 +-- 4 +-- +-- >>> leftmost t2 +-- 1 +-- +leftmost :: Tree -> Int +leftmost = treeFoldr1 (\i _ -> i) + +-- | The integer at the right-most node of a binary tree. +-- +-- >>> rightmost (Leaf 3) +-- 3 +-- +-- >>> rightmost (Node 5 (Leaf 6) (Leaf 7)) +-- 7 +-- +-- >>> rightmost t1 +-- 9 +-- +-- >>> rightmost t2 +-- 9 +-- +rightmost :: Tree -> Int +rightmost = treeFoldl1 (\i _ -> i) + +-- | Get the maximum integer from a binary tree. +-- +-- >>> maxInt (Leaf 3) +-- 3 +-- +-- >>> maxInt (Node 5 (Leaf 4) (Leaf 2)) +-- 5 +-- +-- >>> maxInt (Node 5 (Leaf 7) (Leaf 2)) +-- 7 +-- +-- >>> maxInt t1 +-- 9 +-- +-- >>> maxInt t2 +-- 9 +-- +maxInt :: Tree -> Int +maxInt = treeFoldr1 max + + +-- | Get the minimum integer from a binary tree. +-- +-- >>> minInt (Leaf 3) +-- 3 +-- +-- >>> minInt (Node 2 (Leaf 5) (Leaf 4)) +-- 2 +-- +-- >>> minInt (Node 5 (Leaf 4) (Leaf 7)) +-- 4 +-- +-- >>> minInt t1 +-- 1 +-- +-- >>> minInt t2 +-- 1 +-- +minInt :: Tree -> Int +minInt = treeFoldr1 min + + +-- | Get the sum of the integers in a binary tree. +-- +-- >>> sumInts (Leaf 3) +-- 3 +-- +-- >>> sumInts (Node 2 (Leaf 5) (Leaf 4)) +-- 11 +-- +-- >>> sumInts t1 +-- 45 +-- +-- >>> sumInts (Node 10 t1 t2) +-- 100 +-- +sumInts :: Tree -> Int +sumInts = treeFoldr1 (+) + + +-- | The list of integers encountered by a pre-order traversal of the tree. +-- +-- >>> preorder (Leaf 3) +-- [3] +-- +-- >>> preorder (Node 5 (Leaf 6) (Leaf 7)) +-- [5,6,7] +-- +-- >>> preorder t1 +-- [1,2,3,4,5,6,7,8,9] +-- +-- >>> preorder t2 +-- [6,2,1,4,3,5,8,7,9] +-- +preorder :: Tree -> [ Int ] +preorder = treeFold (:) [] + +-- | The list of integers encountered by an in-order traversal of the tree. +-- +-- >>> inorder (Leaf 3) +-- [3] +-- +-- >>> inorder (Node 5 (Leaf 6) (Leaf 7)) +-- [6,5,7] +-- +-- >>> inorder t1 +-- [4,3,5,2,6,1,8,7,9] +-- +-- >>> inorder t2 +-- [1,2,3,4,5,6,7,8,9] +-- +inorder :: Tree -> [ Int ] +inorder = treeFoldr (:) [] + + +-- | Check whether a binary tree is a binary search tree. +-- +-- >>> isBST (Leaf 3) +-- True +-- +-- >>> isBST (Node 5 (Leaf 6) (Leaf 7)) +-- False +-- +-- >>> isBST t1 +-- False +-- +-- >>> isBST t2 +-- True +-- +isBST :: Tree -> Bool +isBST (Leaf _) = True +isBST (Node i l r) = i >= value l && i <= value r && isBST l && isBST r + where + value (Leaf i) = i + value (Node i _ _) = i + + +-- | Check whether a number is contained in a binary search tree. +-- (You may assume that the given tree is a binary search tree.) +-- +-- >>> inBST 2 (Node 5 (Leaf 2) (Leaf 7)) +-- True +-- +-- >>> inBST 3 (Node 5 (Leaf 2) (Leaf 7)) +-- False +-- +-- >>> inBST 4 t2 +-- True +-- +-- >>> inBST 10 t2 +-- False +-- +inBST :: Int -> Tree -> Bool +inBST i = treeFoldr (\v acc -> acc || (v == i)) False