Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Data.Char
- -- Exercitiul 1
- -- a)
- data Reteta = Stop | R Ing Reteta
- deriving Show
- data Ing = Ing String Int
- deriving Show
- -- a)
- -- Returneaza cantitatea maxima a ingredientului cu numele "nume", case insensitive.
- -- Folosesc map toLower pentru a aplica functia "toLower" tuturor caracterelor dintr-un string.
- r15pmMaxIng :: Reteta -> String -> Int
- r15pmMaxIng Stop _ = 0
- r15pmMaxIng (R (Ing nume_ing cantitate) r) nume =
- let maxRest = r15pmMaxIng r nume in
- if map toLower nume_ing == map toLower nume
- then max cantitate maxRest
- else maxRest
- -- Verifica daca reteta din primul parametru contine ingredientul din al doilea parametru.
- r15pmContine :: Reteta -> Ing -> Bool
- r15pmContine Stop _ = False
- r15pmContine (R ing r) toFind
- | ing == toFind = True
- | otherwise = r15pmContine r toFind
- -- Face tot ce face si r15pmEx1 dar mai are si parametru reteta_initiala.
- -- Aveam nevoie si de parametrul reteta_initiala pentru ca eu caut in reteta initiala cantitatea maxima a ingredientului curent.
- -- Nu e clar din enunt ce sa fac daca am ingrediente duplicate, asa ca le-am eliminat, afisand mereu ultima aparitie.
- -- Daca nu voiam sa le elimin, scoteam "&& not (r15pmContine r (Ing nume_ing cantitate))" din if.
- r15pmEx1_initial :: Reteta -> Reteta -> Reteta
- r15pmEx1_initial Stop _ = Stop
- r15pmEx1_initial (R (Ing nume_ing cantitate) r) reteta_initiala =
- if cantitate == r15pmMaxIng reteta_initiala nume_ing && not (r15pmContine r (Ing nume_ing cantitate))
- then R (Ing nume_ing cantitate) (r15pmEx1_initial r reteta_initiala)
- else r15pmEx1_initial r reteta_initiala
- r15pmEx1 :: Reteta -> Reteta
- r15pmEx1 r = r15pmEx1_initial r r
- -- Pentru testing:
- ex :: Reteta
- ex = R (Ing "faina" 500) (R (Ing "Oua" 4) (R (Ing "faina" 300) Stop))
- retetaGoala :: Reteta
- retetaGoala = Stop
- reteta1 :: Reteta
- reteta1 = R (Ing "branza" 1) (R (Ing "Oua" 5) (R (Ing "brAnza" 20) (R (Ing "OUA" 0) Stop)))
- reteta2 :: Reteta
- reteta2 = R (Ing "branza" 1) (R (Ing "Oua" 5) (R (Ing "brAnza" 1) (R (Ing "OUA" 0) Stop)))
- -- Teste:
- -- 1. ex (dat in enunt): R (Ing "faina" 500) (R (Ing "Oua" 4) Stop)
- -- 2. testReteta: Stop
- -- 3. reteta1: R (Ing "Oua" 5) (R (Ing "brAnza" 20) Stop)
- -- 4. reteta2: R (Ing "Oua" 5) (R (Ing "brAnza" 1) Stop)
- -- b)
- -- Verifica daca doua ingrediente sunt egale ca si nume (case insensitive) si cantitate.
- instance Eq Ing where
- (Ing name1 quantity1) == (Ing name2 quantity2) = map toLower name1 == map toLower name2 && quantity1 == quantity2
- -- Verifica daca reteta din primul parametru contine toate ingredientele din al doilea parametru.
- r15pmContineTot :: Reteta -> Reteta -> Bool
- r15pmContineTot _ Stop = True
- r15pmContineTot Stop _ = False
- r15pmContineTot r1 (R ing r)
- | r15pmContine r1 ing = r15pmContineTot r1 r
- | otherwise = False
- -- Ca doua retete sa fie egale, am folosit dubla incluziune.
- -- Adica prima reteta trebuie sa contina tot ce e in a doua si invers.
- instance Eq Reteta where
- a == b =
- let x = r15pmEx1 a in
- let y = r15pmEx1 b in
- r15pmContineTot x y && r15pmContineTot y x
- -- Pentru testing:
- r1 :: Reteta
- r1 = R (Ing "faina" 500) (R (Ing "oua" 4) (R (Ing "zahar" 500) (R (Ing "faina" 300) Stop)))
- r2 :: Reteta
- r2 = R (Ing "fAIna" 500) (R (Ing "zahar" 500) (R (Ing "Oua" 4) Stop ))
- r3 :: Reteta
- r3 = R (Ing "fAIna" 500) (R (Ing "zahar" 500) (R (Ing "Oua" 55) Stop))
- r4 :: Reteta
- r4 = R (Ing "fAIna" 499) (R (Ing "zahar" 500) (R (Ing "Oua" 55) Stop))
- r5 :: Reteta
- r5 = Stop
- r6 :: Reteta
- r6 = R (Ing "fAIna" 499) (R (Ing "zahar" 500) Stop) -- este continuta de r4
- -- Teste:
- -- 1. r1 == r2 (dat in enunt): True
- -- 2. r2 == r3 (dat in enunt): False
- -- 3. r3 == r3: False
- -- 4. r1 == r5: False
- -- 5. r5 == r5: True
- -- 6. r1 == r1: True
- -- 7. r4 == r6: False
- -- 8. r6 == r4: False
- -- c)
- -- Combina 2 retete (duce b-ul la finalul lui a)
- r15pmCombina :: Reteta -> Reteta -> Reteta
- r15pmCombina a Stop = a
- r15pmCombina Stop a = a
- r15pmCombina (R ing Stop) b = R ing b
- r15pmCombina (R _ r) b = r15pmCombina r b
- data Arb = Leaf Int String | Node Arb Int String Arb
- deriving Show
- r15pmArbToReteta :: Arb -> Reteta
- r15pmArbToReteta (Leaf x nume) = R (Ing nume x) Stop
- r15pmArbToReteta (Node leftArb x nume rightArb) =
- let leftRightReteta = r15pmCombina (r15pmArbToReteta leftArb) (r15pmArbToReteta rightArb) in
- R (Ing nume x) leftRightReteta
- -- Exercitiul 2
- data E x = A | M x Bool (E x)
- -- a)
- instance Foldable E where
- foldMap _ A = mempty
- foldMap f (M x _ e) = foldMap f e `mappend` f x
- -- Pentru testing:
- fTest0 :: Bool
- fTest0 = maximum (M 1 True (M 5 False (M 3 True (M 2 True A)))) == 3
- fTest1 :: Bool
- fTest1 = maximum (M 1 True (M 5 False (M 8 True (M 2 True A)))) == 8
- fTest2 :: Bool
- fTest2 = sum (M 1 True (M 5 True (M 8 True (M 2 True A)))) == 16
- fTest3 :: Bool
- fTest3 = foldr (*) 1 (M 1 True (M 5 True (M 8 True A))) == 40
- -- Teste:
- -- toate True
- -- b)
- class C e where
- cFilter :: (a -> Bool) -> e a -> e a
- toList :: e a -> [a]
- instance C E where
- cFilter _ A = A
- cFilter f (M x b e)
- | not (f x) = M x False (cFilter f e)
- | otherwise = M x b (cFilter f e)
- toList A = []
- toList (M x b e)
- | b = x : toList e
- | otherwise = toList e
- -- Pentru testing:
- cTest0 :: Bool
- cTest0 = toList (cFilter (>2) (M 1 True (M 5 False (M 3 True (M 2 True A))))) == [3]
- cTest1 :: Bool
- cTest1 = toList (cFilter (>2) (M 1 True (M 5 True (M 3 True (M 2 True A))))) == [5, 3]
- cTest2 :: Bool
- cTest2 = toList (cFilter (> 100) (M 1 True (M 5 True (M 3 True (M 2 True A))))) == []
- cTest3 :: Bool
- cTest3 = toList (cFilter (== 5) (M 1 True (M 5 False (M 3 True (M 2 True A))))) == []
- cTest4 :: Bool
- cTest4 = toList (cFilter (== 5) (M 1 True (M 5 False (M 5 True A)))) == [5]
- -- Teste:
- -- toate True
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement