Buscar

Paradigmas de Linguagens de Programação - Lista 2 2016 2

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 6 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 6 páginas

Prévia do material em texto

2ª Lista de Paradigmas de Linguagens Computacionais 
Lista de Exercícios de Revisão do Paradigma Funcional 
 
CIn – UFPE (2016.2) 
Disponível em: 27/09/2016 
 
Professores: 
André Luís de Medeiros Santos (alms@cin.ufpe.br) 
Henrique Emanuel Mostaert Rebêlo (hemr@cin.ufpe.br) 
 
Monitores: 
Álvaro Arthur Canto Sabino de Miranda Costa (aacsmc@cin.ufpe.br) 
Gustavo de Oliveira Feitosa (gof@cin.ufpe.br) 
Ihago Henrique Lucena e Silva (ihls@cin.ufpe.br) 
Luiz Henrique de Souza (lhs2@cin.ufpe.br) 
Renato Vieira Leite de Barros (rvlb@cin.ufpe.br) 
Roberto Costa Fernandes (rcf6@cin.ufpe.br) 
 
1. Apresente a inferência dos tipos das seguintes expressões (função f e função g), 
e dê um exemplo de uso das mesmas com parâmetro(s)/argumento(s) e um 
resultado. 
 
f :: 
f = map ( + ) 
 
g :: 
g = ( . ) map map 
 
Para ajudar a resolver a questão, abaixo estão os tipos de map, ( . ) e ( + ): 
map :: (a -> b) -> [a] -> [b] 
( . ) :: (b -> c) -> (a -> b) -> (a -> c) 
( + ) :: Int -> Int -> Int 
 
2. Qual a diferença entre avaliação estrita e avaliação preguiçosa (lazy evaluation)? 
Mostre exemplos desta diferença. 
 
3. Dado um tipo de dados que representa expressões aritméticas, que podem 
conter operações de soma, subtração, inteiros e variáveis (representada pelo tipo de 
dados Expr, abaixo), faça uma função chamada “avaliar” que, dado uma lista com o 
valor das variáveis e uma expressão, calcule o valor da expressão. 
data Expr = Literal Int -- um número 
 | Soma Expr Expr -- soma as duas expressões 
 | Subtrai Expr Expr -- subtrai a segunda expressão da primeira 
 | Variavel String -- representa uma variável, como “x” ou “y” 
 
avaliar :: [(String, Int)] -> Expr -> Int 
 
Exemplo: 
-- expressão (x + (y - 33)) + (22 + x) 
expressao = Soma (Soma (Variavel “x”) (Subtrai (Variavel “y”) (Literal 33))) (Soma 
(Literal 22) (Variavel “x”)) 
 
-- (avaliar [(“x”, 10), (“y”, 20)] expressao) = 29 
 
 
 
 
 
 
 
 
 
 
Texto para as questões 4 e 5. 
ROT-13 é o nome que se costuma usar para um procedimento simples, mas eficaz 
para garantir que textos eletrônicos não sejam lidos por distração ou acidente. 
ROT-13 vem do inglês, ROTate by 13 places, “ROTacionar 13 posições”. 
 
ROT-13 é uma cifra de César aplicável apenas aos caracteres alfabéticos (da língua 
inglesa) e com passo 13. O algoritmo faz a troca conforme o exemplo abaixo: 
 
 
4 . 
a) Considerando uma chave para representar esta cifra como uma lista de pares 
informando que caracter deve substituir qual outro, implemente uma função cipher 
para realizar esta substituição em uma String, a partir de uma Chave, retornando 
uma String modificada como resultado. Qualquer caracter que não esteja na Chave 
deve aparecer inalterado na String de saída. 
 
type Chave = [(Char, Char)] 
 
rot13parcial :: Chave -- troca ‘a’ por ‘n’, ‘b’ por ‘o’, etc. 
rot13parcial = [(‘a’, ‘n’), (‘b’, ‘o’), (‘c’, ‘p’), (‘d’, ‘q’), (‘e’, ‘r’), (‘f’, ‘s’), 
 (‘g’, ‘t’), (‘h’, ‘u’), (‘i’, ‘v’), (‘j’, ‘w’), (‘k’, ‘x’), (‘l’, ‘y’), (‘m’, ‘z’)] 
 
--cipher :: Chave -> String -> String 
--Exemplo: cipher rot13parcial “hello*hello” = “uryyo*uryyo” 
 
b) Para decifrar o código, é preciso inverter a Chave. Faça uma função que inverta a 
ordem de cada um dos pares de uma Chave (lista de pares de caracteres): 
 
-- inverteChave :: Chave -> Chave 
--Exemplo: inverteChave rot13parcial = [(‘n’, ‘a’), (‘o’, ‘b’), (‘p’, ‘c’), ... 
c) Uma implementação diferente da função cipher poderia usar uma função no lugar 
dos pares de caracteres para representar a chave. Defina esta outra versão da 
função cipher, chamada cipherf. 
 
type FuncaoChave = (Char -> Char) 
 
trocaSoLetraL :: FuncaoChave 
trocaSoLetraL 'l' = 'b' 
trocaSoLetraL c = c 
 
--cipherf :: FuncaoChave -> String -> String 
--Exemplo: cipherf trocaSoLetraL “hello*hello” = “hebbo*hebbo” 
 
d) Usando uma expressão do tipo Chave (lista de pares), você conseguiria gerar 
uma função que pode ser usada como chave para a função cipherf? Em caso 
afirmativo, demonstre. Caso contrário, justifique. 
--chaveToFuncaoChave :: Chave -> FuncaoChave 
--Exemplo: cipherf (chaveToFuncaoChave rot13parcial) “hello*hello” = 
“uryyo*uryyo” 
 
5. Para uma maior eficiência no processo de busca dos caracteres em uma chave, 
podemos fazer a busca dos caracteres a serem trocados usando uma árvore binária 
em que cada nó, além da informação de uma letra e sua substituição, possua sub-
árvores para a busca de letras menores ou maiores que aquela letra. Se a letra não 
for achada na árvore, a substituição não ocorre. Escreva esta função cipherT, que 
usa uma árvore KeyTree definida abaixo. 
 
data KeyTree = Empty | Node Char Char KeyTree KeyTree 
 
chaveParcial :: KeyTree 
chaveParcial = Node ‘h’ ‘u’ (Node ‘c’ ‘p’ (Node ‘b’ ‘o’ (Node ‘a’ ‘n’ Empty Empty) 
Empty) (Node ‘e’ ‘r’ Empty Empty)) (Node ‘l’ ‘y’ Empty (Node ‘m’ ‘z’ Empty Empty)) 
 
--cipherT :: KeyTree -> String -> String 
--Exemplo: cipherT chaveParcial “hello*hello” = “uryyo*uryyo” 
 
Texto para as questões de 6 a 10. 
Dado um tabuleiro de Jogo de Damas representado pelos seguintes tipos de dados: 
 
data Peca = P | B | V deriving (Eq, Show) 
type Tabuleiro = [[Peca]] 
 
Onde P representa uma peça preta, B uma peça branca e V uma casa vazia. O 
primeiro elemento da primeira lista é o elemento (0, 0) e a primeira peça preta está 
na posição (0, 0) (linha 0, coluna 0). Sabendo que um tabuleiro tem tamanho 8 x 8 
e que as peças se movem na diagonal para espaços vazios (desconsidere a captura 
de peças), defina as seguintes funções: 
 
tabuleiroInicial :: Tabuleiro 
tabuleiroInicial = [[P, V, P, V, P, V, P, V], 
 [V, P, V, P, V, P, V, P], 
 [P, V, P, V, P, V, P, V], 
 [V, V, V, V, V, V, V, V], 
 [V, V, V, V, V, V, V, V], 
 [V, B, V, B, V, B, V, B], 
 [B, V, B, V, B, V, B, V], 
 [V, B, V, B, V, B, V, B]] 
 
 
 
 
6. count :: Tabuleiro -> (Int, Int), que conta quantas peças brancas e quantas peças 
pretas estão no tabuleiro. 
 
7. tabuleiroValido :: Tabuleiro -> Bool, que verifica se o tabuleiro tem tamanho 
8 x 8 e se as peças existentes estão em casas válidas, sempre na diagonal. 
Exemplo: 
--tabuleiroValido tabuleiroInicial = True 
 
8. promoveDama :: Tabuleiro -> Bool, que verifica se tem alguma peça branca na 
primeira linha ou se tem alguma peça preta na última linha, ou seja, se existe alguma 
peça no tabuleiro que poderia ser promovida a dama. 
Exemplo: 
--promoveDama tabuleiroInicial = False 
 
9. verificaJogada :: (Int, Int) -> (Int, Int) -> Tabuleiro -> Bool, que verifica se uma 
jogada é possível/válida, ou seja, se é uma jogada de uma casa que tem uma peça 
para outra vazia na diagonal. 
Exemplos: 
--verificaJogada (2, 0) (3, 1) tabuleiroInicial = True 
--verificaJogada (2, 0) (3, 2) tabuleiroInicial = False 
--verificaJogada (2, 0) (3, 3) tabuleiroInicial = False 
 
10. move :: (Int, Int) -> (Int, Int) -> Tabuleiro -> Tabuleiro, que move uma peça de 
uma casa para outra, contando as linhas e colunas a partir do primeiro elemento da 
primeira lista sendo o elemento (0, 0). Essa função recebe a casa inicial, a casa 
final, o tabuleiro inicial e retorna um novo tabuleiro modificado.

Outros materiais