Questões

50 questoes from site of the professora Sofia

  1. Apresente uma definição recursiva da função (pré-definida) enumFromTo :: Int -> Int -> [Int] que constrói a lista dos números inteiros comprendidos entre dois limites. Por exemplo, enumFromTo 1 5 corresponde à lista [1, 2, 3, 4, 5]
enumFromTo' :: Int -> Int -> [Int]
enumFromTo' a b | a > b     = []
                | otherwise = a : enumFromTo' (a+1) b
enumFromTo' :: Int -> Int -> [Int] 
enumFromTo' a b | a <= b = [a..b]
                | otherwise = [a, a-1..b]
  1. Apresente uma definição recursiva da função (pré-definida) enumFromThenTo :: Int -> Int -> Int -> [Int] que constrói a lista dos números inteiros compreendidos entre dois limites e espaçados de um valor constante. Por exemplo, enumFromThenTo 1 3 10 corresponde à lista [1, 3, 5, 7, 9]
enumFromThenTo' :: Int -> Int -> Int -> [Int]
enumFromThenTo' x y z = [x, x+(y-x)..z] 
  1. Apresente uma definição recursiva da função (pré-definida) (++) :: [a] -> [a] -> [a] que concatena duas listas. Por exemplo, (++) [1, 2, 3] [10, 20, 30] corresponde à lista [1, 2, 3, 4, 10, 20, 30].
maisMais :: [a] -> [a] -> [a] 
maisMais [] l = l 
maisMais (h:t) (x:xs) = h : maisMais t (x:xs)
  1. Apresente uma definição recursiva da função (pré-definida) (!!) :: [a] -> Int -> a que dada uma lista e um inteiro, calcula o elemento da lista que se encontra nessa posição (assume-se que o primeiro elemento se encontra na posição 0). Por exemplo, (!!) [10, 20, 30] 1 corresponde a 20. Ignore os casos em que a função não se encontra definida (i.e., em que a posição fornecida não corresponde a nenhuma posição válida da lista).
bangBang :: [a] -> Int -> a
bangBang (h:t) n 
    | n <= 0 = h 
    | otherwise = bangBang t (n-1) 
  1. Apresente uma definição recursiva da função (pré-definida) reverse :: [a] -> [a] que dada uma lista calcula uma lista com os elementos dessa lista pela ordem inversa. Por exemplo, reverse [10, 20, 30] corresponde a [30, 20, 10].
reverse' :: [a] -> [a] 
reverse' [] = [] 
reverse' (h:t) = reverse' t ++ [h] 
  1. Apresente uma definição recursiva da função (pré-definida) take :: Int -> [a] -> [a] que dado um inteiro n e uma lista l calcula a lista com os (no máximo) n primeiros elementos de l. A lista resultado só terá menos de que n elementos se a lista l tiver menos do que n elementos. Nesse caso a lista calculada é igual à lista fornecida. Por exemplo, take 2 [10, 20, 30] corresponde a [10, 20]
take :: Int -> [a] -> [a]
take _ [] = []
take n _ 
	| n <= 0 = []
take n (h:t) = h . take (n - 1) t
  1. Apresente uma definição recursiva da função (pré-definida) drop :: Int -> [a] -> [a] que dado um inteiro n e uma lista l calcula a lista se os (no máximo) n primeiros elementos de l. Se a lista fornecida não tiver n elementos ou menos, a lista resultante será vazia. Por exemplo, drop 2 [10, 20, 30] corresponde a [30].
drop' :: Int -> [a] -> [a]
drop' n l | n <= 0 = l
drop' x [] = []
drop' x (h : t)
  | x == 1 = t
  | otherwise = drop' (x - 1) t
  1. Apresente uma definição recursiva da função (pré-definida) zip :: [a] -> [b] -> [(a, b)] constói uma lista de pares a partir de duas listas. Por exemplo, zip [1, 2, 3] [10, 20, 30, 40] corresponde [(1, 10), (2, 20), (3, 30)].
zip :: [a] -> [b] -> [(a, b)]
zip [] [] = []
zip [] _ = []
zip _ [] = []
zip (x:xs) (y:ys) = (x, y) : zip xs ys
  1. Apresente uma definição recursiva da função (pré-definida) replicate :: Int -> a -> [a] que dado um inteiro n e um elemento x constói uma lista com n elementos, todos iguais a x. Por exemplo, replicate 3 10 corresponde a [10, 10, 10].
replicate :: Int -> a -> [a]
replicate n x
	| n <= 0 = []
	| otherwise = x : replicate (n - 1) x
  1. Apresente uma definição recursiva da função (pré-definida) intersperse :: a -> [a] -> [a] que, dado um elemento e uma lista, constrói uma lista em que o elemento fornecido é intercalado entre os elementos da lista fornecida.
intersperce :: a -> [a] -> [a]
intersperce x [] = []
intersperce x [z] = [z]
intersperce x (h : t) = h : x : intersperce x t
  1. Apresente uma definição recursiva da função (pré-definida) group :: Eq a => [a] -> [[a]] que agrupa elementos iguais e consecutivos de uma lista. Exemplo
> group [1,2,2,3,4,4,4,5,4]
[[1],[2,2],[3],[4,4,4],[5],[4]]
group :: (Eq a) => [a] -> [[a]]
group [x] = [[x]]
group (h : t)
	| h `elem` (head gt) = (h : (head gt)) : tail gt
	| otherwise = [h] : gt
	where
		gt = group t
  1. Apresente uma definição recursiva da função (pré-definida) concat :: [[a]] -> [a] que concatena as listas de uma lista.
> concat [[1],[2,2],[3],[4,4,4],[5],[4]]
[1,2,2,3,4,4,4,5,4]
concat :: [[a]] -> [a]
concat [] = []
concat [[x]] = [x]
concat (h : xs) = h ++ concat xs
  1. Apresente uma definição recursiva da função (pré-definida) inits :: [a] -> [[a]] que calcula a lista dos prefixos de uma lista.
> inits [11,21,13]
[[],[11],[11,21],[11,21,13]]
inits :: [a] -> [[a]]
inits [] = [[]]
inits l@(h : t) = l : xs
	where 
		xs = inits t
  1. Apresente uma definição recursiva da função (pré-definida) tails :: [a] -> [[a]] que calcula a lista dos sufixos de uma lista.
> tails [1,2,3]
[[1,2,3],[2,3],[3],[]]
  1. Defina a função heads :: [[a]] -> [a] que recebe uma lista de listas e produz a lista com o primeiro elemento de cada lista.
> heads [[2,3,4],[1,7],[],[8,5,3]]
[2,1,8]
heads :: [[a]] -> [a]
heads [[]] = []
heads (h : t)
	| null h = heads t
	| otherwise = head h : heads t
  1. Defina a função total :: [[a]] -> Int que recebe uma lista de listas e conta o total de elementos (de todas as listas).
> total [[2,3,4],[1,7],[],[8,5,3]]
8
total :: [[a]] -> Int
total [] = 0
total (h : t) =
  let total1 :: [a] -> Int
      total1 [] = 0
      total1 [x] = 1
      total1 (h : t) = 1 + total1 t
   in total1 h + total t
  1. Defina a função fun :: [(a,b,c)] -> [(a,c)] que recebe uma lista de triplos e produz a lista de pares com o primeiro e o terceiro elemento de cada triplo.
> fun [("rui",3,2), ("maria",5,2), ("ana",43,7)]
[("rui",2), ("maria",2), ("ana",7)]
fun :: [(a, b, c)] -> [(a, c)]
fun [] = []
fun ((x, y, z) : t) = (x, z) : fun t
  1. Defina a função cola :: [(String,b,c)] -> String que recebe uma lista de triplos e concatena as strings que estão na primeira componente dos triplos.
> cola [("rui",3,2), ("maria",5,2), ("ana",43,7)]
"ruimariaana"
cola :: [(String, b, c)] -> String
cola l = concat $ map (\(string, _, _) -> string) l
  1. Defina a função idade :: Int -> Int -> [(String,Int)] -> [String] que recebe o ano, a idade e uma lista de pares com o nome e o ano de nascimento de cada pessoa, e devolve a listas de nomes das pessoas que nesse ano atingirão ou já ultrapassaram a idade indicada.
> idade 2021 26 [("rui",1995), ("maria",2009), ("ana",1947)]
["rui","ana"]
idade :: Int -> Int -> [(String, Int)] -> [String]
idade _ _ [] = []
idade ano edad lista = [nome | (nome, nasc) <- lista, ano - nasc >= edad]
  1. Apresente uma definição recursiva da função powerEnumFrom :: Int -> Int -> [Int] que dado um valor n e um valor m constrói a lista [n^0,…,n^(m−1)].
> powerEnumFrom 2 10
[1,2,4,8,16,32,64,128,256,512]
powerEnumFrom :: Int -> Int -> [Int]
powerEnumFrom n m = aux 0
  where
    aux k
      | k >= m = []
      | otherwise = n ^ k : aux (k + 1)
  1. Apresente uma definição recursiva da função isPrime :: Int -> Bool que dado um número inteiro maior ou igual a 2 determina se esse número é primo. Para determinar se um número n é primo, descubra se existe algum número inteiro m tal que . Se um tal número não existir então n é primo, e se existir então n não é primo.
> isPrime 7
True
> isPrime 21
False
isPrime :: Int -> Bool
isPrime x =
  let prime n = [m | m <- [2 .. (n - 1)], m * m > n, mod n m == 0]
   in (null $ prime x) && (x > 1)
  1. Apresente uma definição recursiva da função (pré-definida) isPrefixOf :: Eq a => [a] -> [a] -> Bool que testa se uma lista é prefixo de outra.
> isPrefixOf [10,20] [10,20,30]
True
> isPrefixOf [10,30] [10,20,30]
False
isPrefixOf1 :: (Eq a) => [a] -> [a] -> Bool
isPrefixOf1 lista1 lista2 = lista1 == lista3
  where
    lista3 = take (length lista1) lista2
isPrefixOf :: (Eq a) => [a] -> [a] -> Bool
isPrefixOf [] _ = True
isPrefixOf _ [] = False
isPrefixOf (h : t) (x : xs) = if h == x then isPrefixOf t xs else False
  1. Apresente uma definição recursiva da função (pré-definida) isSuffixOf :: Eq a => [a] -> [a] -> Bool que testa se uma lista é sufixo de outra.
> isSuffixOf [20,30] [10,20,30]
True
> isSuffixOf [10,30] [10,20,30]
False
isSuffixOf :: (Eq a) => [a] -> [a] -> Bool
isSuffixOf lista1 lista2 = isPrefixOf (reverse lista1) (reverse lista2)
  1. Apresente uma definição recursiva da função (pré-definida) isSubsequenceOf :: Eq a => [a] -> [a] -> Bool que testa se os elementos de uma lista ocorrem noutra pela mesma ordem relativa.
> isSubsequenceOf [20,40] [10,20,30,40]
True
> isSubsequenceOf [40,20] [10,20,30,40]
False
isSubsequenceOf :: (Eq a) => [a] -> [a] -> Bool
isSubsequenceOf [] _ = True
isSubsequenceOf _ [] = False
isSubsequenceOf lista@(x : xs) (y : ys)
  | x == y = isSubsequenceOf xs ys
  | otherwise = isSubsequenceOf lista ys
  1. Apresente uma definição recursiva da função (pré-definida) elemIndices :: Eq a => a -> [a] -> [Int] que calcula a lista de posições em que um dado elemento ocorre numa lista.
> elemIndices 3 [1,2,3,4,3,2,3,4,5]
[2,4,6]
elemIndices :: (Eq a) => a -> [a] -> [Int]
elemIndices _ [] = []
elemIndices x lista = aux 0 lista
  where
    aux :: Int -> [a] -> [Int]
    aux _ [] = []
    aux i (y : ys) = if x == y then i : aux (i + 1) ys else aux (i + 1) ys
  1. Apresente uma definição recursiva da função (pré-definida) nub :: Eq a => [a] -> [a] que calcula uma lista com os mesmos elementos da recebida, sem repetições.
> nub [1,2,1,2,3,1,2]
[1,2,3]
nub :: (Eq a) => [a] -> [a]
nub [] = []
nub (h : t) = h : nub (filter (/= h) t)
  1. Apresente uma definição recursiva da função (pré-definida) delete :: Eq a => a -> [a] -> [a] que retorna a lista resultante de remover (a primeira ocorrência de) um dado elemento de uma lista.
> delete 2 [1,2,1,2,3,1,2]
[1,1,2,3,1,2]
> delete 4 [1,3,2,1,3,5]
[1,3,2,1,3,5]
delete :: (Eq a) => a -> [a] -> [a]
delete _ [] = []
delete x (h : t)
  | x == h = t
  | otherwise = h : delete x t
  1. Apresente uma definição recursiva da função (pré-definida) (\) :: Eq a => [a] -> [a] -> [a] que retorna a lista resultante de remover (as primeiras ocorrências) dos elementos da segunda lista da primeira.
> (\\) [1,2,3,4,5,1] [1,5]
[2,3,4,1]
(\\) :: (Eq a) => [a] -> [a] -> [a]
(\\) lista [] = lista
(\\) [] _ = []
(\\) lista (h : t) = (\\) (delete h lista) t
  1. Apresente uma definição recursiva da função (pré-definida) union :: Eq a => [a] -> [a] -> [a] que retorna a lista resultante de acrescentar à primeira lista os elementos da segunda que não ocorrem na primeira.
> union [1,1,2,3,4] [1,5]
[1,1,2,3,4,5]
union :: (Eq a) => [a] -> [a] -> [a]
union [] lista = lista
union lista [] = lista
union (h : t) ys = h : union t (delete h ys)
  1. Apresente uma definição recursiva da função (pré-definida) intersect :: Eq a => [a] -> [a] -> [a] que retorna a lista resultante de remover da primeira lista os elementos que não pertencem à segunda.
> intersect [1,1,2,3,4] [1,3,5]
[1,1,3]
intersect :: (Eq a) => [a] -> [a] -> [a]
intersect [] _ = []
intersect _ [] = []
intersect (h : t) lista
  | h `elem` lista = h : intersect t lista
  | otherwise = intersect t lista
  1. Apresente uma definição recursiva da função (pré-definida) insert :: Ord a => a -> [a] -> [a] que dado um elemento e uma lista ordenada retorna a lista resultante de inserir ordenadamente esse elemento na lista.
> insert 25 [1,20,30,40]
[1,20,25,30,40]
insert :: (Ord a) => a -> [a] -> [a]
insert x [] = [x]
insert x lista@(h : t)
  | x == h = lista
  | x < h = x : lista
  | otherwise = h : insert x t
  1. Apresente uma definição recursiva da função (pré-definida) unwords :: [String] -> String que junta todas as strings da lista numa só, separando-as por um espaço.
> unwords ["Programacao", "Funcional"]
"Programacao Funcional"
unwords :: [String] -> String
unwords [] = []
unwords [x] = x
unwords (h : t) = h ++ " " ++ unwords t
  1. Apresente uma definição recursiva da função (pré-definida) unlines :: [String] -> String que junta todas as strings da lista numa só, separando-as pelo caracter ’ ’.
> unlines ["Prog", "Func"]
"Prog\nFunc\n"
unlines :: [String] -> String
unlines [] = []
unlines (h : t) = h ++ "\n" ++ unlines t
  1. Apresente uma definição recursiva da função pMaior :: Ord a => [a] -> Int que dada uma lista não vazia, retorna a posição onde se encontra o maior elemento da lista. As posições da lista começam em 0, i.e., a função deverá retornar 0 se o primeiro elemento da lista for o maior.
> pMaior [2,6,3,1,5,4]
1
> pMaior [30,10,20,40,0]
3
pMaior :: (Ord a) => [a] -> Int
pMaior [x] = 0
pMaior l@(h : t) = aux 0 (0, h) l
  where
    aux _ (pos, _) [] = pos
    aux i (pos, max) (x : xs)
      | x > max = aux (i + 1) (i, x) xs
      | otherwise = aux (i + 1) (pos, max) xs
  1. Apresente uma definição recursiva da função (pré-definida) lookup :: Eq a => a -> [(a,b)] -> Maybe b que retorna uma lista construída a partir de elementos de uma lista (o segundo argumento) atendendo a uma condição dada pelo primeiro argumento.
> lookup 'a' [('a',1),('b',4),('c',5)]
Just 1
lookup :: (Eq a) => a -> [(a, b)] -> Maybe b
lookup _ [] = Nothing
lookup k ((a, b) : t) = if k == a then Just b else lookup k t
  1. Defina a função preCrescente :: Ord a => [a] -> [a] que calcula o maior prefixo crescente de uma lista.
> preCrescente [3,7,9,6,10,22]
[3,7,9]
preCrescente :: (Ord a) => [a] -> [a]
preCrescente [x] = [x]
preCrescente [] = []
preCrescente (h : x : t)
  | h < x = h : preCrescente (x : t)
  | otherwise = [h]
  1. Apresente uma definição recursiva da função iSort :: Ord a => [a] -> [a] que calcula o resultado de ordenar uma lista. Assuma, se precisar, que existe definida a função insert :: Ord a => a -> [a] -> [a] que dado um elemento e uma lista ordenada retorna a lista resultante de inserir ordenadamente esse elemento na lista.
> iSort [3,1,2,5,4]
[1,2,3,4,5]
iSort :: (Ord a) => [a] -> [a]
iSort [] = []
iSort [x] = [x]
iSort (h : t) = insert h (iSort t)
  1. Apresente uma definição recursiva da função menor :: String -> String -> Bool que dadas duas strings, retorna True se e só se a primeira for menor do que a segunda, segundo a ordem lexicográfica (i.e., do dicionário).
> menor "sai" "saiu"
True
> menor "programacao" "funcional"
False
menor :: String -> String -> Bool
menor [] [] = False
menor [] _ = True
menor _ [] = False
menor (h : t) (x : xs)
  | h < x = True
  | h == x = menor t xs
  | otherwise = False
  1. Considere que se usa o tipo [(a,Int)] para representar multi-conjuntos de elementos de a. Considere ainda que nestas listas não há pares cuja primeira componente coincida, nem cuja segunda componente seja menor ou igual a zero.

Defina a função elemMSet :: Eq a => a -> [(a,Int)] -> Bool que testa se um elemento pertence a um multi-conjunto.

> elemMSet ’a’ [(’b’,2), (’a’,4), (’c’,1)]
True
> elemMSet ’d’ [(’b’,2), (’a’,4), (’c’,1)]
False
elemMSet :: (Eq a) => a -> [(a, Int)] -> Bool
elemMSet _ [] = False
elemMSet x ((x1, _) : t) = if x == x1 then True else elemMSet x t
  1. Considere que se usa o tipo [(a,Int)] para representar multi-conjuntos de elementos de a. Considere ainda que nestas listas não há pares cuja primeira componente coincida, nem cuja segunda componente seja menor ou igual a zero.

Defina a função converteMSet :: [(a,Int)] -> [a] que converte um multi-conjuto na lista dos seus elementos.

> converteMSet [(’b’,2), (’a’,4), (’c’,1)]
"bbaaaac"
converteMSet :: [(a, Int)] -> [a]
converteMSet [] = []
converteMSet ((x, n) : t) = (replicate' n x) ++ converteMSet t
  1. Considere que se usa o tipo [(a,Int)] para representar multi-conjuntos de elementos de a. Considere ainda que nestas listas não há pares cuja primeira componente coincida, nem cuja segunda componente seja menor ou igual a zero.

Defina a função insereMSet :: Eq a => a -> [(a,Int)] -> [(a,Int)] que acrescenta um elemento a um multi-conjunto.

> insereMSet ’c’ [(’b’,2), (’a’,4), (’c’,1)]
[(’b’,2),(’a’,4), (’c’,2)]
insereMSet :: (Eq a) => a -> [(a, Int)] -> [(a, Int)]
insereMSet x [] = [(x, 1)]
insereMSet a ((x, n) : t) = if a == x then (x, n + 1) : t else (x, n) : insereMSet a t
  1. Considere que se usa o tipo [(a,Int)] para representar multi-conjuntos de elementos de a. Considere ainda que nestas listas não há pares cuja primeira componente coincida, nem cuja segunda componente seja menor ou igual a zero.

Defina a função removeMSet :: Eq a => a -> [(a,Int)] -> [(a,Int)] que remove um elemento a um multi-conjunto. Se o elemento não existir, deve ser retornado o multi-conjunto recebido.

> removeMSet ’c’ [(’b’,2), (’a’,4), (’c’,1)]
[(’b’,2),(’a’,4)]
removeMSet :: (Eq a) => a -> [(a, Int)] -> [(a, Int)]
removeMSet _ [] = []
removeMSet obj ((x, n) : t)
  | n > 1 = if obj == x then (x, n - 1) : t else (x, n) : removeMSet obj t
  | otherwise = if obj == x then t else (x, n) : removeMSet obj t
  1. Considere que se usa o tipo [(a,Int)] para representar multi-conjuntos de elementos de a. Considere ainda que nestas listas não há pares cuja primeira componente coincida, nem cuja segunda componente seja menor ou igual a zero.

Defina a função constroiMSet :: Ord a => [a] -> [(a,Int)] que, dada uma lista ordenada por ordem crescente, calcula o multi-conjunto dos seus elementos.

> constroiMSet "aaabccc"
[(’a’,3), (’b’,1), (’c’,3)]
constroiMSet :: (Ord a) => [a] -> [(a, Int)]
constroiMSet [] = []
constroiMSet (h : t) = insereMSet (h) (constroiMSet t)
  1. Apresente uma definição recursiva da função pré-definida partitionEithers :: [Either a b] -> ([a],[b]) que divide uma lista de Either em duas listas.
> partitionEithers [Left 1, Right 2, Left 3, Right 4, Left 5]
([1,3,5],[2,4])
partitionEithers :: [Either a b] -> ([a], [b])
partitionEithers [] = ([], [])
partitionEithers ((Left x) : t) = (x : a, b)
  where
    (a, b) = partitionEithers t
partitionEithers ((Right x) : t) = (a, x : b)
  where
    (a, b) = partitionEithers t
  1. Apresente uma definição recursiva da função pré-definida catMaybes :: [Maybe a] -> [a] que coleciona os elementos do tipo a de uma lista.
> catMaybes [Just 1, Just 2, Nothing, Just 3, Nothing, Just 4, Just 5, Nothing]
[1,2,3,4,5]
catMaybes :: [Maybe a] -> [a]
catMaybes [] = []
catMaybes (h : t) =
  case h of
    Just x -> x : catMaybes t
    Nothing -> catMaybes t
  1. Considere o seguinte tipo para representar movimentos de um robot.

data Movimento = Norte | Sul | Este | Oeste deriving Show

Defina a função caminho :: (Int,Int) -> (Int,Int) -> [Movimento] que, dadas as posições inicial e final (coordenadas) do robot, produz uma lista de movimentos suficientes para que o robot passe de uma posição para a outra.

> caminho (0,0) (3,4)
[Este,Este,Este,Norte,Norte,Norte,Norte]
caminho :: (Int, Int) -> (Int, Int) -> [Movimento]
caminho (xi, yi) (xf, yf)
  | xi < xf = Este : caminho (xi + 1, yi) (xf, yf)
  | xi > xf = Oeste : caminho (xi - 1, yi) (xf, yf)
  | yi < yf = Norte : caminho (xi, yi + 1) (xf, yf)
  | yi > yf = Sul : caminho (xi, yi - 1) (xf, yf)
  | otherwise = []
  1. Considere o seguinte tipo para representar movimentos de um robot.

data Movimento = Norte | Sul | Este | Oeste deriving Show

Defina a função hasLoops :: (Int,Int) -> [Movimento] -> Bool que, dada uma posição inicial e uma lista de movimentos (correspondentes a um percurso), verifica se o robot alguma vez volta a passar pela posição inicial ao longo do percurso correspondente. Pode usar a função posicao definida acima.

> hasLoops (0,0) [Norte, Norte, Este, Sul, Oeste, Sul, Este, Norte, Este]
True
> hasLoops (2,1) [Sul, Este, Sul, Oeste, Norte, Este, Sul]
False
hasLoops :: (Int, Int) -> [Movimento] -> Bool
hasLoops inicio movimientos = aux [inicio] inicio movimientos
  where
    aux _ _ [] = False
    aux visitados (x, y) (m : ms) =
      let proxima = case m of
            Norte -> (x, y + 1)
            Sul -> (x, y - 1)
            Este -> (x + 1, y)
            Oeste -> (x - 1, y)
       in if proxima `elem` visitados then True else aux (proxima : visitados) proxima ms
  1. Considere os seguintes tipos para representar pontos e retângulos, respectivamente. Assuma que os retângulos têm os lados paralelos aos eixos e são representados apenas por dois dos pontos mais afastados.

type Ponto = (Float,Float) data Rectangulo = Rect Ponto Ponto

Defina a função contaQuadrados :: [Rectangulo] -> Int que, dada uma lista com retângulos, conta quantos deles são quadrados.

> contaQuadrados [Rect (0,0) (2,2), Rect (1,3) (7,4), Rect (5,2) (8,5), Rect (1,2) (2,4)]
2
contaQuadrados :: [Rectangulo] -> Int
contaQuadrados [] = 0
contaQuadrados ((Rect (x, y) (a, b)) : t)
  | abs (x - a) == abs (y - b) = 1 + contaQuadrados t
  | otherwise = contaQuadrados t
  1. Considere os seguintes tipos para representar pontos e retângulos, respectivamente. Assuma que os retângulos têm os lados paralelos aos eixos e são representados apenas por dois dos pontos mais afastados.

type Ponto = (Float,Float) data Rectangulo = Rect Ponto Ponto

Defina a função areaTotal :: [Rectangulo] -> Float que, dada uma lista com retângulos, determina a área total que eles ocupam.

> areaTotal [Rect (0,0) (2,2), Rect (1,3) (7,4), Rect (5,2) (8,5), Rect (1,2) (2,4)]
21.0
areaTotal :: [Rectangulo] -> Float
areaTotal lista = sum (map (\(Rect (x, y) (z, w)) -> abs (x - z) * abs (y - w)) lista)
  1. Considere o seguinte tipo para representar o estado de um equipamento.

data Equipamento = Bom | Razoavel | Avariado deriving Show

Defina a função naoReparar :: [Equipamento] -> Int que determina a quantidade de equipamentos que não estão avariados

> naoReparar [Bom, Avariado, Bom, Razoavel, Avariado]
3
naoReparar :: [Equipamento] -> Int
naoReparar [] = 0
naoReparar (h : t) =
  case h of
    Avariado -> naoReparar t
    _ -> 1 + naoReparar t