-
Notifications
You must be signed in to change notification settings - Fork 0
/
lyh.hs
140 lines (113 loc) · 3.73 KB
/
lyh.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
--
-- Learn you a haskell.
--
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= skinny = "You're underweight, you emo, you!"
| bmi <= normal = "You're supposedly normal. Pffft, I bet you're ugly!"
| bmi <= fat = "You're fat! Lose some weight, fatty!"
| otherwise = "You're a whale, congratulations!"
where bmi = weight / height ^ 2
(skinny, normal, fat) = (18.5, 25.0, 30.0)
calcBmis :: (RealFloat a) => [(a, a)] -> [a]
calcBmis xs =
[bmi w h | (w, h) <- xs]
where bmi weight height = weight / height ^ 2
-- head
head' :: [a] -> a
head' xs = case xs of [] -> error "No head for empty lists!"
(x:_) -> x
-- maximum with accumulator
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "empty list"
maximum' (x:[]) = x
maximum' (x:xs) =
maxAcc xs x
where maxAcc [] a = a
maxAcc (y:ys) a
| y >= a = maxAcc ys y
| otherwise = maxAcc ys a
-- quicksort
quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
let smaller = quicksort [ a | a <- xs, a <= x]
bigger = quicksort [ a | a <- xs, a > x]
in smaller ++ [x] ++ bigger
-- with partitioning function mostly following
-- http://en.literateprograms.org/Quicksort_(Haskell)
part :: Ord a => a -> [a] -> ([a],[a],[a]) -> ([a],[a],[a])
-- e lst l e g partitioned
part _ [] (l,e,g) = (l,e,g)
-- if the head of the list
-- bigger: append go the greater list g
-- smaller: append to the smaller list l
-- equal: append to the equal list e
part p (x:xs) (l,e,g)
| x > p = part p xs (l , e , x:g)
| x < p = part p xs (x:l, e , g)
| otherwise = part p xs (l , x:e, g)
qs2 :: Ord a => [a] -> [a]
qs2 [] = []
qs2 (x:xs) =
qs2 smaller ++ equal ++ qs2 bigger
where
(smaller, equal, bigger) = part x xs ([],[x],[])
-- l e g
-- List.map2 from F#
-- http://msdn.microsoft.com/en-us/library/ee340232.aspx
map2 :: (a -> b -> c) -> [a] -> [b] -> [c]
map2 f _ [] = []
map2 f [] _ = []
map2 f (x:xs) (y:ys) = f x y : map2 f xs ys
-- with accumulator.
-- todo -- remove the extra reverse
map2Acc :: (a -> b -> c) -> [a] -> [b] -> [c] -> [c]
map2Acc f _ [] acc = reverse acc
map2Acc f [] _ acc = reverse acc
map2Acc f (x:xs) (y:ys) acc = map2Acc f xs ys ((f x y) : acc)
-- maxi fold
maxfold :: Ord a => [a] -> a
maxfold [] = error "empty"
maxfold lst = foldr (\a b -> if a > b then a else b) f lst
where f = head lst
-----------------------------------------------------------
-- Tree stuff.
data Tree a =
EmptyTree
| Node a (Tree a) (Tree a)
deriving (Show, Read, Eq)
singleton :: a -> Tree a
singleton x = Node x EmptyTree EmptyTree
treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = singleton x
treeInsert x (Node a left right)
| x == a = Node x left right
| x < a = Node a (treeInsert x left) right
| x > a = Node a left (treeInsert x right)
treeMember :: (Ord a) => a -> Tree a -> Bool
treeMember x EmptyTree = False
treeMember x (Node a left right)
| x == a = True
| x < a = treeMember x left
| x > a = treeMember x right
data LTree a =
LEmptyTree
| LNode a [LTree a]
deriving (Show, Read, Eq)
lsingleton :: a -> LTree a
lsingleton x = LNode x []
ltreeInsert :: (Ord a) => a -> LTree a -> LTree a
ltreeInsert x LEmptyTree = lsingleton x
ltreeInsert x (LNode a lst) =
let newl = (lsingleton x) : lst in
(LNode a newl)
ltreeDepth :: LTree a -> Integer
ltreeDepth LEmptyTree = 0
ltreeDepth (LNode a lst) =
ltreeDepthRec 0 (LNode a lst)
where
ltreeDepthRec cur LEmptyTree = cur
ltreeDepthRec cur (LNode x []) = cur
ltreeDepthRec cur (LNode x lst1) =
maximum $ map (ltreeDepthRec $ cur + 1) lst1