Recursos-LCC

Um arquivo de todo material que consegui reunir, pertinente ao curso de LCC da UM.

View on GitHub
import Data.Maybe (fromMaybe)

-- Exercicio 1

type MSet a = [(a,Int)]

ex1 :: MSet Char
ex1 = [('b',4),('a',2),('c',1)]

cardMSet ::  MSet a -> Int
cardMSet = foldr ((+) . snd) 0

moda :: MSet a -> [a]
moda = fst . foldr (\(x,n) (acc,accn) -> if n >= accn then (if n > accn then [x] else x:acc,n) else (acc,accn)) ([],0)

converteMSet :: MSet a -> [a]
converteMSet = foldr (\(x,n) -> (++) $ replicate n x) []

addNcopies :: Eq a => MSet a -> a -> Int -> MSet a
addNcopies mset elm num = foldr (\(x,n) -> (:) (x,n + (if x == elm then num else 0))) [] mset

-- Exercicio 2

data SReais = AA Double Double | FF Double Double
            | AF Double Double | FA Double Double
            | Uniao SReais SReais

ex2 :: SReais
ex2 = Uniao (Uniao (AA 4.2 5.5) (AF 3.1 7.0)) (FF (-12.3) 30.0)

instance Show SReais where
    show (Uniao a b) = "(" ++ show a ++ " U " ++ show b ++ ")"
    show intv = ch1 ++ num1 ++ "," ++ num2 ++ ch2
        where (ch1,num1,num2,ch2) = case intv of AA a b -> ("]",show a,show b,"[")
                                                 AF a b -> ("]",show a,show b,"]")
                                                 FA a b -> ("[",show a,show b,"[")
                                                 FF a b -> ("[",show a,show b,"]")

pertence :: Double -> SReais -> Bool
pertence num (Uniao a b) = pertence num a || pertence num b
pertence num intv = (af1 && num >= num1 || num > num1) && (af2 && num <= num2 || num < num2)
    where (af1,num1,num2,af2) = case intv of AA a b -> (False,a,b,False)
                                             AF a b -> (False,a,b,True)
                                             FA a b -> (True,a,b,False)
                                             FF a b -> (True,a,b,True)

tira ::  Double -> SReais -> SReais
tira n (Uniao a b) | pertence n a = Uniao (tira n a) b
                   | pertence n b = Uniao a (tira n b)
                   | otherwise = (Uniao a b)
tira n intv = case intv of AA a b -> if n > a && n < b then (Uniao (AA a n) (AA n b)) else intv
                           AF a b -> if n == b then AA a b else if n > a && n < b then (Uniao (AA a n) (AF n b)) else intv
                           FA a b -> if n == a then AA a b else if n > a && n < b then (Uniao (FA a n) (AA n b)) else intv
                           FF a b -> if n == b then FA a b else if n == a then AF a b else if n > a && n < b then (Uniao (FA a n) (AF n b)) else intv

-- Exercicio 3

data RTree a = R a [RTree a]

percorre :: [Int] -> RTree a -> Maybe [a]
percorre [] (R a _) = Just [a]
percorre _ (R a []) = Nothing
percorre (h:t) (R a r) | length r < h || null auxX = Nothing
                       | otherwise = Just (a:auxX)
    where aux = percorre t (r !! (h - 1))
          auxX = fromMaybe [] aux

procura :: Eq a => a -> RTree a -> Maybe [Int]
procura n (R a r) | n == a = Just []
                  | null r = Nothing
                  | otherwise = foldl (\acc num -> if procura n (r !! (num - 1)) == Nothing then acc else Just (num:fromMaybe [] (procura n (r !! (num - 1))))) Nothing [1..length r]