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