Advertisement
Mihai_Preda

Untitled

Feb 1st, 2021
484
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import Data.Char
  2.  
  3. -- Exercitiul 1
  4.  
  5. -- a)
  6.  
  7. data Reteta =  Stop | R Ing Reteta
  8.          deriving Show
  9.  
  10. data Ing = Ing String Int
  11.          deriving Show
  12.  
  13.  
  14. -- a)
  15.  
  16. -- Returneaza cantitatea maxima a ingredientului cu numele "nume", case insensitive.
  17. -- Folosesc map toLower pentru a aplica functia "toLower" tuturor caracterelor dintr-un string.
  18. r15pmMaxIng :: Reteta -> String -> Int
  19. r15pmMaxIng Stop _ = 0
  20. r15pmMaxIng (R (Ing nume_ing cantitate) r) nume =
  21.     let maxRest = r15pmMaxIng r nume in
  22.         if map toLower nume_ing == map toLower nume
  23.             then max cantitate maxRest
  24.         else maxRest
  25.  
  26. -- Verifica daca reteta din primul parametru contine ingredientul din al doilea parametru.
  27. r15pmContine :: Reteta -> Ing -> Bool
  28. r15pmContine Stop _ = False
  29. r15pmContine (R ing r) toFind
  30.     | ing == toFind = True
  31.     | otherwise = r15pmContine r toFind
  32.  
  33. -- Face tot ce face si r15pmEx1 dar mai are si parametru reteta_initiala.
  34. -- Aveam nevoie si de parametrul reteta_initiala pentru ca eu caut in reteta initiala cantitatea maxima a ingredientului curent.
  35. -- Nu e clar din enunt ce sa fac daca am ingrediente duplicate, asa ca le-am eliminat, afisand mereu ultima aparitie.
  36. -- Daca nu voiam sa le elimin, scoteam "&& not (r15pmContine r (Ing nume_ing cantitate))" din if.
  37. r15pmEx1_initial :: Reteta -> Reteta -> Reteta
  38. r15pmEx1_initial Stop _ = Stop
  39. r15pmEx1_initial (R (Ing nume_ing cantitate) r) reteta_initiala =
  40.     if cantitate == r15pmMaxIng reteta_initiala nume_ing && not (r15pmContine r (Ing nume_ing cantitate))
  41.         then R (Ing nume_ing cantitate) (r15pmEx1_initial r reteta_initiala)
  42.         else r15pmEx1_initial r reteta_initiala
  43.  
  44. r15pmEx1 :: Reteta -> Reteta
  45. r15pmEx1 r = r15pmEx1_initial r r
  46.  
  47.  
  48. -- Pentru testing:
  49.  
  50. ex :: Reteta
  51. ex = R (Ing "faina" 500) (R  (Ing "Oua" 4) (R (Ing "faina" 300) Stop))
  52.  
  53. retetaGoala :: Reteta
  54. retetaGoala = Stop
  55.  
  56. reteta1 :: Reteta
  57. reteta1 = R (Ing "branza" 1) (R  (Ing "Oua" 5) (R (Ing "brAnza" 20) (R (Ing "OUA" 0) Stop)))
  58.  
  59. reteta2 :: Reteta
  60. reteta2 = R (Ing "branza" 1) (R  (Ing "Oua" 5) (R (Ing "brAnza" 1) (R (Ing "OUA" 0) Stop)))
  61.  
  62. -- Teste:
  63. -- 1. ex (dat in enunt): R (Ing "faina" 500) (R (Ing "Oua" 4) Stop)
  64. -- 2. testReteta: Stop
  65. -- 3. reteta1: R (Ing "Oua" 5) (R (Ing "brAnza" 20) Stop)
  66. -- 4. reteta2: R (Ing "Oua" 5) (R (Ing "brAnza" 1) Stop)
  67.  
  68. -- b)
  69.  
  70. -- Verifica daca doua ingrediente sunt egale ca si nume (case insensitive) si cantitate.
  71. instance Eq Ing where
  72.     (Ing name1 quantity1) == (Ing name2 quantity2) = map toLower name1 == map toLower name2 && quantity1 == quantity2
  73.  
  74. -- Verifica daca reteta din primul parametru contine toate ingredientele din al doilea parametru.
  75. r15pmContineTot :: Reteta -> Reteta -> Bool
  76. r15pmContineTot _ Stop = True
  77. r15pmContineTot Stop _ = False
  78. r15pmContineTot r1 (R ing r)
  79.     | r15pmContine r1 ing = r15pmContineTot r1 r
  80.     | otherwise = False
  81.  
  82. -- Ca doua retete sa fie egale, am folosit dubla incluziune.
  83. -- Adica prima reteta trebuie sa contina tot ce e in a doua si invers.
  84. instance Eq Reteta where
  85.     a == b =
  86.         let x = r15pmEx1 a in
  87.             let y = r15pmEx1 b in
  88.                 r15pmContineTot x y && r15pmContineTot y x
  89.  
  90.  
  91. -- Pentru testing:
  92. r1 :: Reteta
  93. r1 =  R (Ing "faina" 500) (R (Ing "oua" 4) (R  (Ing "zahar" 500) (R (Ing "faina" 300) Stop)))
  94. r2 :: Reteta
  95. r2 =  R (Ing "fAIna" 500) (R (Ing "zahar" 500) (R (Ing "Oua" 4) Stop ))
  96. r3 :: Reteta
  97. r3 =  R (Ing "fAIna" 500) (R (Ing "zahar" 500) (R  (Ing "Oua" 55) Stop))
  98. r4 :: Reteta
  99. r4 =  R (Ing "fAIna" 499) (R (Ing "zahar" 500) (R  (Ing "Oua" 55) Stop))
  100. r5 :: Reteta
  101. r5 = Stop
  102. r6 :: Reteta
  103. r6 = R (Ing "fAIna" 499) (R (Ing "zahar" 500) Stop) -- este continuta de r4
  104.  
  105. -- Teste:
  106. -- 1. r1 == r2 (dat in enunt): True
  107. -- 2. r2 == r3 (dat in enunt): False
  108. -- 3. r3 == r3: False
  109. -- 4. r1 == r5: False
  110. -- 5. r5 == r5: True
  111. -- 6. r1 == r1: True
  112. -- 7. r4 == r6: False
  113. -- 8. r6 == r4: False
  114.  
  115.  
  116. -- c)
  117. -- Combina 2 retete (duce b-ul la finalul lui a)
  118. r15pmCombina :: Reteta -> Reteta -> Reteta
  119. r15pmCombina a Stop = a
  120. r15pmCombina Stop a = a
  121. r15pmCombina (R ing Stop) b = R ing b
  122. r15pmCombina (R _ r) b = r15pmCombina r b
  123.  
  124. data Arb = Leaf Int String | Node Arb Int String Arb
  125.          deriving  Show
  126.  
  127. r15pmArbToReteta :: Arb -> Reteta
  128. r15pmArbToReteta (Leaf x nume) = R (Ing nume x) Stop
  129. r15pmArbToReteta (Node leftArb x nume rightArb) =
  130.     let leftRightReteta = r15pmCombina (r15pmArbToReteta leftArb) (r15pmArbToReteta rightArb) in
  131.         R (Ing nume x) leftRightReteta
  132.  
  133.  
  134.  
  135. -- Exercitiul 2
  136. data E x = A | M x Bool (E x)
  137.  
  138. -- a)
  139. instance Foldable E where
  140.     foldMap _ A = mempty
  141.     foldMap f (M x _ e) = foldMap f e `mappend` f x
  142.  
  143. -- Pentru testing:
  144. fTest0 :: Bool
  145. fTest0 = maximum (M 1 True (M 5 False (M 3 True (M 2 True A)))) == 3
  146. fTest1 :: Bool
  147. fTest1 = maximum (M 1 True (M 5 False (M 8 True (M 2 True A)))) == 8
  148. fTest2 :: Bool
  149. fTest2 = sum (M 1 True (M 5 True (M 8 True (M 2 True A)))) == 16
  150. fTest3 :: Bool
  151. fTest3 = foldr (*) 1 (M 1 True (M 5 True (M 8 True A))) == 40
  152.  
  153.  
  154. -- Teste:
  155. -- toate True
  156.  
  157. -- b)
  158. class C e where
  159.   cFilter :: (a -> Bool) -> e a -> e a
  160.   toList :: e a -> [a]
  161.  
  162. instance C E where
  163.     cFilter _ A = A
  164.     cFilter f (M x b e)
  165.         | not (f x) = M x False (cFilter f e)
  166.         | otherwise = M x b (cFilter f e)
  167.     toList A = []
  168.     toList (M x b e)
  169.         | b = x : toList e
  170.         | otherwise = toList e
  171.  
  172.  
  173. -- Pentru testing:
  174. cTest0 :: Bool
  175. cTest0 = toList  (cFilter (>2) (M 1 True (M 5 False (M 3 True (M 2 True A))))) == [3]
  176. cTest1 :: Bool
  177. cTest1 = toList  (cFilter (>2) (M 1 True (M 5 True (M 3 True (M 2 True A))))) == [5, 3]
  178. cTest2 :: Bool
  179. cTest2 = toList  (cFilter (> 100) (M 1 True (M 5 True (M 3 True (M 2 True A))))) == []
  180. cTest3 :: Bool
  181. cTest3 = toList  (cFilter (== 5) (M 1 True (M 5 False (M 3 True (M 2 True A))))) == []
  182. cTest4 :: Bool
  183. cTest4 = toList  (cFilter (== 5) (M 1 True (M 5 False (M 5 True A)))) == [5]
  184.  
  185. -- Teste:
  186. -- toate True
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement