Preview only show first 10 pages with watermark. For full document please download

Programação Funcional ... Exercícios Resolvidos - Trabalho De Pf - Final

Coleção completa de exercícios resolvidos em haskell

   EMBED


Share

Transcript

UNIVERSIDADE FEDERAL DE UBERLÂNDIA FACULDADE DE COMPUTAÇÃO - FACOM CIÊNCIA DA COMPUTAÇÃO DISCIPLINA: PROGRAMAÇÃO FUNCIONAL– GBC033 PROFESSORA: Maria Adriana Vidigal de Lima TRABALHO DE PROMAÇÃO FUNCIONAL BRUNO FRANCO OLIVEIRA VICTOR DE PAULA Fernandes Pereira UBERLÂNDIA, ABRIL 2013 BRUNO FRANCO OLIVEIRA – 11021BCC003 VICTOR DE PAULA Fernandes Pereira– 11121BCC034 TÍTULOS DE CAPITALIZAÇÃO Trabalho apresentado como requisito parcial de avaliação na disciplina de Programação Funcional do Curso de Ciência da Computação da Faculdade de Computação, sob a orientação da professora Maria Adriana Vidigal de Lima. UBERLÂNDIA, ABRIL 2013 1) Seja uma agência bancária que deseja vender titulos de capitalização para seus correntistas. O título é adquirido em apenas uma parcela. Cada correntista pode comprar um título (apenas um). Cada título de capitalização deve ser definido por uma tupla com os seguintes dados: • Numero da Conta • Data da compra (tupla com dia, mês e ano) • Valor escolhido (300, 500, 1000 e 1500) Assim, podemos ter os exemplos abaixo como tuplas para títulos de capitalização: (“689232”, (25,10,2011), 1000) (“236333”, (27,10,2011), 300) (“546544”, (08,11,2011), 1500) (“975457”, (16,11,2011), 1000) 2) Crie uma estrutura de árvore de busca binária para armazenar as compras de títulos de capitalização dos correntistas. A seguir defina uma função inserir para guardar cada título na árvore, usando o número da conta de comparação. A função inserir deve garantir que não seja registrado mais de um título por correntista. 3) Ao final do prazo para a venda dos títulos devem-se começar os sorteios, que acontecem semanalmente. O valor a pagar ao correntista sorteado é 1000 vezes o valor escolhido. Para isso: A) Faça uma função que retira os elementos (apenas os números da conta) da árvore de busca binária, e os coloca numa lista, usando a estratégia da pós-ordem. B) Usando um número qualquer como entrada, faça uma função sorteio, que realiza um percurso circular na lista e devolve o numero da conta sorteada. No percurso circular, deve-se, ao chegar no final da lista, começar novamente do início da mesma até que o número de entrada seja igual a um. Ex: > sorteio 10 [“689232”,“236333”, “546544”, “975457”] “236333” C) Para cada conta sorteada, removê-la da árvore binária para que um novo sorteio possa ser realizado. Respostas: module TrabalhoHaskell where ---Exercicio 01-------------------------------------------------------------- --Definição dos tipos de dados --DataCompra e uma tupla formada por tres numeros inteiros type DataCompra = (Integer,Integer,Integer) --Elem e uma tupla formada por uma String, uma tupla Data e um numero Inteiro type Elem = (String,DataCompra,Integer) --Definição do tipo de dados da arvore --ArvTitCap e um tipo generico definido para uma arvore de busca binaria com a definicao de Null caso seja vazia e para um no data ArvTitCap = Null | No Elem ArvTitCap ArvTitCap deriving (Show,Eq) ---Exercicio 02---------------------------------------------------------------Arvore Binaria com os seus nos pre-definidos --Definição da arvore arv::ArvTitCap arv = (No ("689232", (25,10,2013), 1000) (No ("546544", (08,11,2013), 1500) (No ("236333", (27,10,2013), 300) Null Null) Null)(No ("975457", (16,11,2013), 1000) Null Null)) --Função de inserção auxiliar --A funcao insereArv e definida em sua entrada um item que e uma tupla e Null para o caso base e e inserido um no que sera um no raiz, caso nao seja --Vazia a arvore, o no e inserido no lado menor que o no da raiz que e o esquerda, ou no lado direito que e maior que o no da raiz inserirArv::ArvTitCap->Elem->ArvTitCap inserirArv Null item = (No item Null Null) inserirArv (No (n,d,v) esq dir) (numCont,dataCompra,valor) | (numCont == n) = error "Matricula Repitida!!!" | (numCont < n) = (No (n,d,v) (inserirArv esq (numCont,dataCompra,valor)) dir) --se o novo no for maior que a raiz, eu chamo recursivamente andando pela parte esquerda da arvore | otherwise = (No (n,d,v) esq (inserirArv dir (numCont,dataCompra,valor)))--se o novo no for menor que a raiz, eu chamo recursivamente andando pela parte direita da arvore --Ex: -- >inserirArv arv ("123456",(27,11,2013),300) --No ("689232",(25,10,2013),1000) (No ("546544",(8,11,2013),1500) (No ("236333",(27,10,2013),300) (No ("123456",(27,11,2013),300) Null Null) Null) Null) (No ("975457",(16,11,2013),1000) Null Null) --Verifica se os valores são validos, ou seja se são 300, 500. 1000. ou 1500 insere::Elem->ArvTitCap->ArvTitCap insere x Null = (No x Null Null) insere (a,b,c) (No y esq dir) = if((c == 300) || (c == 500) || (c == 1000) || (c == 1500)) then inserirArv (No y esq dir) (a,b,c) else error "Valores invalidos" -- obs (No (n,d,v)) vem antes da chamada recursiva para nao ser perdido o no raiz da arvore --Ex: -- > insere ("489012",(12,09,2013),1000) arv --No ("689232",(25,10,2013),1000) (No ("546544",(8,11,2013),1500) (No ("236333",(27,10,2013),300) Null (No ("489012",(12,9,2013),1000) Null Null)) Null) (No ("975457",(16,11,2013),1000) Null Null) --Funcao que pega uma arvore e a converte para a notacao posOrdem --PosOrdem::ArvTitCap->[Char] posOrdem Null = [] posOrdem (No (x,y,z) esq dir) = (posOrdem esq)++(posOrdem dir)++[x] --Ex: -- > posOrdem arv --["236333","546544","975457","689232"] --Calcula o enesimo elemento para ser utilizado na função sorteio enesimo 1 (y:ys) = y enesimo 0 x = enesimo (length x) x enesimo x (y:ys)= enesimo (x-1) ys --Ex: -- > enesimo 3 (posOrdem arv) --"975457" --Passa o número de vezes que irá percorrer e a função posOrdme que irá retornar uma lista de String provenientes da arovore sorteio::Int->[String]->String sorteio x xs = enesimo(mod x(length xs)) xs--Realiza o percorrimento circular --Ex: -- > sorteio 4 (posOrdem arv) --"689232" --Funcao que remove uma string especifica da arvore e retorna a arvore sem o no da string removido remove1::[Char]->ArvTitCap->ArvTitCap remove1 x Null = Null remove1 x (No (a,b,c) esq dir) | x < a = No (a,b,c) (remove1 x esq) dir | x > a = No (a,b,c) esq (remove1 x dir) | esq == Null = dir | dir == Null = esq | otherwise = junta esq dir --Ex: -- > remove1 "689232" arv --No ("975457",(16,11,2013),1000) (No ("546544",(8,11,2013),1500) (No ("236333",(27,10,2013),300) Null Null) Null) Null --Funcao que remove um no especifico da arvore e retorna a arvore sem o no removido remove::Elem->ArvTitCap->ArvTitCap remove x Null = Null remove x (No v esq dir) | x < v = No v (remove x esq) dir | x > v = No v esq (remove x dir) | esq == Null = dir | dir == Null = esq | otherwise = junta esq dir --Ex: -- > remove ("975457",(16,11,2013),1000) arv --No ("689232",(25,10,2013),1000) (No ("546544",(8,11,2013),1500) (No ("236333",(27,10,2013),300) Null Null) Null) Null --Funcao que junta duas arvores junta::ArvTitCap->ArvTitCap->ArvTitCap junta esq dir = No menorAux esq novadir where menorAux = menor dir novadir = remove menorAux dir --Ex: -- > junta arv arv --No ("236333",(27,10,2013),300) (No ("689232",(25,10,2013),1000) (No ("546544",(8,11,2013),1500) (No ("236333",(27,10,2013),300) Null Null) Null) (No ("975457",(16,11,2013),1000) Null Null)) (No ("689232",(25,10,2013),1000) (No ("546544",(8,11,2013),1500) Null Null) (No ("975457",(16,11,2013),1000) Null Null)) --Funcao que retorna o menor no de uma arvore menor::ArvTitCap -> Elem menor Null = undefined menor (No x esq dir) | esq == Null = x | otherwise = menor esq --Ex: -- > menor arv --("236333",(27,10,2013),300) ---Exercicio 03-------------------------------------------------------------- --Sorteia um núemero e retira da arvore sorteioAlterado::Int->[String]->ArvTitCap sorteioAlterado x xs = (remove1(sorteio x xs) arv) --Ex: -- > sorteioAlterado 3 (posOrdem arv) --No ("689232",(25,10,2013),1000) (No ("546544",(8,11,2013),1500) (No ("236333",(27,10,2013),300) Null Null) Null) Null