Advertisement
Guest User

Untitled

a guest
Apr 28th, 2015
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.42 KB | None | 0 0
  1. {-# OPTIONS_GHC -F -pgmF htfpp #-}
  2.  
  3. import Data.List
  4. import Data.Array
  5. import Test.Framework
  6.  
  7. {-
  8. 1. (2p)
  9. Având dat tipul de date Vector, definiți funcțiile care calculează distanța
  10. euclidiană, suma și produsul scalar dintre doi vectori dați.
  11. -}
  12.  
  13. test_vector :: IO ()
  14. test_vector = do
  15. assertBool $ eqHelper 2.29128 (distVec v1 v2)
  16. assertBool $ eqHelperVec (Vector 5 10 5.5) (sumVec v1 v2)
  17. assertBool $ eqHelper 37.5 (dotProdVec v1 v2)
  18. where
  19. eps = 0.01
  20. eqHelper x y = abs (x - y) <= eps
  21. eqHelperVec (Vector x1 y1 z1) (Vector x2 y2 z2) =
  22. eqHelper x1 x2 && eqHelper y1 y2 && eqHelper z1 z2
  23. v1 = (Vector 2 4 3)
  24. v2 = (Vector 3 6 2.5)
  25.  
  26. data Vector = Vector
  27. { vx :: Double
  28. , vy :: Double
  29. , vz :: Double
  30. } deriving (Show, Eq)
  31.  
  32. distVec :: Vector -> Vector -> Double
  33. distVec (Vector x1 y1 z1) (Vector x2 y2 z2) = sqrt $ dx + dy + dz
  34. where
  35. square x = x * x
  36. dx = square $ x1 - x2
  37. dy = square $ y1 - y2
  38. dz = square $ z1 - z2
  39.  
  40. sumVec :: Vector -> Vector -> Vector
  41. sumVec (Vector x1 y1 z1) (Vector x2 y2 z2) = Vector sx sy sz
  42. where
  43. sx = x1 + x2
  44. sy = y1 + y2
  45. sz = z1 + z2
  46.  
  47. dotProdVec :: Vector -> Vector -> Double
  48. dotProdVec (Vector x1 y1 z1) (Vector x2 y2 z2) = px + py + pz
  49. where
  50. px = x1 * x2
  51. py = y1 * y2
  52. pz = z1 * z2
  53.  
  54. {-
  55. 2. (3p)
  56. Definiți un tip de date SList a care să aibă funcționalități asemănătoare
  57. listelor din Scheme, permițând componente la diferite niveluri de imbricare.
  58. Ex: Lista din Scheme '(1 (3 4) (2)) să poată fi definită în Haskell folosind
  59. SList.
  60. Adițional, definiti:
  61. - emptySList, lista vidă
  62. - consElem, adaugă un element în capul unei liste
  63. Ex: consElem 1 '((3 4) (2)) == '(1 (3 4) (2))
  64. - consList, adaugă o listă (imbricată) în capul unei liste
  65. Ex: consList '(2 3) '(1 2) == '((2 3) 1 2)
  66. - headSList, ia primul element dintr-un SList
  67. - tailSList, ia restul SList-ului
  68. - deepEqual, o funcție ce verifică egalitatea a două SList
  69. Notare:
  70. (1p) definirea tipului de date, emptySList, consElem și consList
  71. (1p) headSList și tailSList
  72. (1p) deepEqual
  73. -}
  74.  
  75. test_slist :: IO ()
  76. test_slist = do
  77. assertBool $ deepEqual (consElem 2 emptySList)
  78. (consList (headSList l1) emptySList)
  79. assertBool $ deepEqual l2 (tailSList l1)
  80. where
  81. l1 = consElem 2 $ consList (consElem 1 $ consElem 1 emptySList) $
  82. consElem 3 emptySList
  83. l2 = consList (consElem 1 $ consElem 1 emptySList) $ consElem 3 emptySList
  84.  
  85. data SList a = Atom a | List [SList a] deriving Show
  86.  
  87. append (List a) (List b) = List $ a ++ b
  88. append (List a) (Atom b) = List $ a ++ [Atom b]
  89. append (Atom a) (List b) = List $ Atom a : b
  90. append (Atom a) (Atom b) = List [Atom a, Atom b]
  91.  
  92. emptySList :: SList a
  93. emptySList = List []
  94.  
  95. consElem :: a -> SList a -> SList a
  96. consElem x xs = append (Atom x) xs
  97.  
  98. consList :: SList a -> SList a -> SList a
  99. consList x (Atom y) = List [x, Atom y]
  100. consList x (List ys) = List $ x : ys
  101.  
  102. headSList :: SList a -> SList a
  103. headSList (List x) = head x
  104. headSList _ = error "head undefined on Atoms"
  105.  
  106. tailSList :: SList a -> SList a
  107. tailSList (List x) = List $ tail x
  108. tailSList _ = error "tail undefined on Atoms"
  109.  
  110. deepEqual :: Eq a => SList a -> SList a -> Bool
  111. deepEqual (Atom x) (Atom y) = x == y
  112. deepEqual (List []) (List []) = True
  113. deepEqual (List x) (List y) = deepEqual (head x) (head y) &&
  114. deepEqual (List $ tail x) (List $ tail y)
  115. deepEqual _ _ = False
  116.  
  117. {-
  118. 3. (3p)
  119. Definiti un tip de date BST a pentru a implementa un arbore binar de cautare.
  120. De asemenea, definiti functii pentru a crea un arbore binar de cautare de la
  121. o lista de elemente, cautarea unui element intr-un arbore binar de cautare si
  122. o functie care intoarce lista elementelor din parcurgerea in preordine a
  123. arborelui.
  124.  
  125. Hint: Este de preferat ca arborele binar de cautare sa fie balansat, lucru
  126. usor de obtinut la creare daca lista de elemente este sortata
  127. -}
  128.  
  129. test_bst :: IO ()
  130. test_bst = do
  131. assertEqual (Just 1) $ findElem bst 1
  132. assertEqual [3,2,1,4] $ preorder bst
  133. where
  134. bst = makeBST [2,3,1,4]
  135.  
  136.  
  137. data BST a = BSTNod a (BST a) (BST a) | BSTNil deriving Show
  138.  
  139. makeBST :: Ord a => [a] -> BST a
  140. makeBST lst = makeBSTHelper (sort lst)
  141.  
  142. makeBSTHelper [] = BSTNil
  143. makeBSTHelper lst = BSTNod m (makeBSTHelper st) (makeBSTHelper dr)
  144. where
  145. l = length lst
  146. m = lst !! (div l 2)
  147. st = take (div l 2) lst
  148. dr = drop ((div l 2) + 1) lst
  149.  
  150. findElem :: (Ord a, Eq a) => BST a -> a -> Maybe a
  151. findElem BSTNil _ = Nothing
  152. findElem (BSTNod x arbSt arbDr ) y
  153. | x == y = Just x
  154. | y < x = findElem arbSt y
  155. | otherwise = findElem arbDr y
  156.  
  157. preorder :: BST a -> [a]
  158. preorder BSTNil = []
  159. preorder (BSTNod x arbSt arbDr) = [x] ++ (preorder arbSt) ++ (preorder arbDr)
  160.  
  161. {-
  162. 4. (2p)
  163. Având dat tipul BinaryTree a din cadrul exercițiilor rezolvate, definiți
  164. funcția subtree, care verifică dacă arborele t1 este un subarbore al
  165. arborelui t2.
  166. Ex: subtree (makeBinTree [1,2]) (makeBinTree [1,2,3,4]) == True
  167. -}
  168.  
  169. test_subtree :: IO ()
  170. test_subtree = do
  171. assertBool $ subtree (Leaf 1) t
  172. assertBool $ subtree (makeBinTree [1,2]) t
  173. assertBool $ subtree (makeBinTree [3,4]) t
  174. assertBool $ not $ subtree (makeBinTree [2,3]) t
  175. where
  176. t = makeBinTree [1,2,3,4]
  177.  
  178. data BinaryTree a = Node (BinaryTree a) (BinaryTree a) | Leaf a deriving Show
  179.  
  180. makeBinTree :: [a] -> BinaryTree a
  181. makeBinTree lst = head $ mergeUpwards leafList
  182. where
  183. leafList = map (\x -> Leaf x) lst
  184. mergeUpwards [] = []
  185. mergeUpwards [x] = [x]
  186. mergeUpwards (x:y:xs) = mergeUpwards ( (Node x y) : mergeUpwards xs)
  187.  
  188. equalTree :: Eq a => BinaryTree a -> BinaryTree a -> Bool
  189. equalTree (Leaf x) (Leaf y) = x == y
  190. equalTree (Node x1 x2) (Node y1 y2) =
  191. equalTree x1 y1 && equalTree x2 y2
  192. equalTree _ _ = False
  193.  
  194. subtree :: Eq a => BinaryTree a -> BinaryTree a -> Bool
  195. subtree t (Node x y) =
  196. equalTree t (Node x y) || subtree t x || subtree t y
  197. subtree t1 t2 = equalTree t1 t2
  198.  
  199. {-
  200. 5. (BONUS, 2p)
  201. Implementați o tabelă de dispersie, i.e. un vector de lungime fixă de
  202. „bucket”-uri, fiecare „bucket” conținând o listă de elemente având un tip
  203. arbitrar. Adăugarea elementelor în tabela de dispersie va fi făcută după o
  204. funcție de dispersie având tipul HashFunc a: aplicarea funcției de dispersie
  205. asupra elementului va da indexul „bucket”-ului unde va fi adăugat acesta.
  206.  
  207. Vor fi implementate tipul de date HashTable a, tabela vidă emptyH și
  208. funcțiile insertH și findH, pentru inserarea și respectiv regăsirea
  209. elementelor în tabelă. Dorim să accesăm „bucket”-urile în O(1), motiv pentru
  210. care se cere folosirea tipului Array din modulul Data.Array. Pentru n
  211. „bucket”-uri, indexarea va fi făcută de la 0 la n - 1.
  212.  
  213. Funcțiile relevante din Data.Array sunt: array (inițializare), (//)
  214. (actualizare), (!) (indexare).
  215. http://hackage.haskell.org/package/array-0.5.0.0/docs/Data-Array.html#t:Array
  216.  
  217. Atenție, o tabelă va fi definită pe baza structurii propriu-zise și a
  218. funcției de dispersie, motiv pentru care funcția de dispersie *trebuie* să
  219. fie parte din definiția tipului de date.
  220.  
  221. Mai multe detalii la:
  222. https://en.wikipedia.org/wiki/Hash_table
  223. -}
  224.  
  225. test_hash :: IO ()
  226. test_hash = do
  227. let hf = (`mod` nb) . length
  228. nb = 3
  229. h1 = emptyH nb hf
  230. h2 = insertH "abc" $ insertH "d" $ insertH "ef" h1
  231. h3 = insertH "ghci" h2
  232. assertEqual Nothing $ findH "d" h1
  233. assertEqual (Just "d") $ findH "d" h2
  234. assertEqual (Just "abc") $ findH "abc" h2
  235. assertEqual (Just "ef") $ findH "ef" h2
  236. assertEqual (Just "ghci") $ findH "ghci" h3
  237.  
  238. type HashFunc a = a -> Int
  239. data HashTable a = HashTable
  240. { buckets :: Array Int [a]
  241. , hashfunc :: HashFunc a
  242. }
  243.  
  244. -- emptyH numar_bucketuri functie_hash
  245. emptyH :: Int -> HashFunc a -> HashTable a
  246. emptyH n = HashTable $ array (0, n - 1) [(i, []) | i <- [0..n - 1]]
  247.  
  248. insertH :: a -> HashTable a -> HashTable a
  249. insertH x ht = HashTable bs hf
  250. where
  251. hf = hashfunc ht
  252. i = hf x
  253. l = buckets ht ! i
  254. bs = buckets ht // [(i, x : l)]
  255.  
  256. findH :: Eq a => a -> HashTable a -> Maybe a
  257. findH x ht = if x `elem` l then Just x else Nothing
  258. where
  259. l = buckets ht ! hashfunc ht x
  260.  
  261. -- functie auxiliara, utila pentru afisarea HashTable
  262. showHT :: Show a => HashTable a -> String
  263. showHT = show . buckets
  264.  
  265. runTests :: IO ()
  266. runTests = htfMain htf_thisModulesTests
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement