Skip to content

Instantly share code, notes, and snippets.

@iuridiniz
Created September 24, 2011 23:50
Show Gist options
  • Save iuridiniz/1240009 to your computer and use it in GitHub Desktop.
Save iuridiniz/1240009 to your computer and use it in GitHub Desktop.
(UFRN) Exercícios de Haskell da disciplina LPCP (UFRN 2005 - LPCP)
Exercícios de Haskell da disciplina LPCP (UFRN 2005 - LPCP)
-- Expert System
module ExpertSystem where
import IOExts
perguntas :: [String]
r_escritorio :: [[String]]
r_programacao :: [[String]]
r_servidor :: [[String]]
r_render_3d :: [[String]]
fazer_perguntas_aux :: [String] -> [String] -> IO [String]
fazer_perguntas :: [String] -> [String]
isMember :: [String] -> [[String]] -> Bool
comparar :: [String] -> [ ([[String]], String) ] -> String
-- Nossas perguntas.
perguntas = [
"Qual a sua cpu?\n[0] < 500 Mhz\n[1] >= 500 Mhz\n", -- x <- [0,1]
"Qual a quantidade de memoria RAM?\n[0] < 128 MB\n[1] 128~512MB\n[2] > 512MB\n", -- y <- [0,1,2]
"Qual o barramento da sua placa VGA?\n[0] < 128 bits\n[1] >= 128 bits\n", -- z <- [0,1]
"Qual o tamanho do seu HD?\n[0] < 80 GB\n[1] >= 80 GB\n"] -- t <- [0,1]
-- Nossa Base de dados.
r_escritorio = [ [x,y,z,t] | x <- ["0","1"], y <- ["0","1","2"], z <- ["0","1"], t <- ["0","1"], x == "0", y == "0" || y == "1" ]
r_programacao = [ ["0","2","0","0"], ["1","0","0","0"], ["1","0","1","0"], ["1","1","0","0"], ["1","2","0","0"] ]
r_servidor = [ ["0","2","0","1"], ["1","0","0","1"], ["1","0","1","1"], ["1","1","0","1"], ["1","2","0","1"] ]
r_render_3d = [ ["0","2","1","0"], ["0","2","1","1"], ["1","1","1","0"], ["1","1","1","1"], ["1","2","1","0"], ["1","2","1","1"] ]
-- Funcao auxiliar para entrada e saida, necessita converter ainda (IO String par String).
fazer_perguntas_aux [] res = return res
fazer_perguntas_aux (h:tail) res = do
putStr (h)
r <- getLine
fazer_perguntas_aux tail (res ++ [r])
-- onde 'x' sao as perguntas. (converter 'IO String' para 'String')
-- isto gera o vetor de respostas do usuario.
fazer_perguntas x = unsafePerformIO ( fazer_perguntas_aux x [])
-- Verifica se um elemente pertence ao conjuto
isMember a conjunto = [ x | x <- conjunto, x == a ] /= []
-- compara as respostas com a base de dados
comparar r [] = "Inconclusivo, voce respondeu corretamente?"
comparar r (h:tail)
| isMember r (fst h) = (snd h)
| otherwise = comparar r tail
main = do
putStr(comparar (fazer_perguntas perguntas) [
(r_escritorio ,"Uso recomendado: Escritorio\n"),
(r_programacao,"Uso recomendado: Programacao\n"),
(r_servidor ,"Uso recomendado: Servidor\n"),
(r_render_3d ,"Uso recomendado: Renderizacao 3D\n")])
-- p1
-- Construa a funcao ocorrencias::Int->[Int]->Int que, dada uma
-- lista de inteiros e um valor inteiro, retorne o numero de
-- ocorrencias desse valor na lista
ocorrencias :: Int -> [Int] -> Int
-- tamanho da lista: 'x' pertece a 'l' tal que 'x' == 'n'
ocorrencias n l = length [ x | x <- l, x == n ]
-- p10
-- Dado um numero inteiro positivo n, contrua uma lista com todos
-- os pares de inteiros positivos cuja soma de elementos seja igual a n.
pares :: Int -> [(Int,Int)]
pares n = [ (x,y) | x <- [0..n], y <- [0..n], x + y == n]
-- p2
-- Construa a funcao unicos::[Int]->[Int] que dada uma lsita de inteiros,
-- retorna uma lista contendo os valores que ocorrem apenas uma vez na
-- lista de entrada.
unicos :: [Int] -> [Int]
isMember :: Int -> [Int] -> Bool
elimina :: Int -> [Int] -> [Int]
isMember n lista = [ x | x <- lista, n == x ] /= []
elimina n lista = [ x | x <- lista, x /= n]
unicos [] = []
-- se a cabeca aparece na calda:
-- elimina cabeca da calda e faz recursao sobre o resultado
-- se nao adiciona cabeca mais recusao sobre a calda
unicos (h:tail)
| isMember h tail = unicos (elimina h tail)
| otherwise = [h] ++ unicos tail
-- p3
-- Defina a funcao desloque::[Int]->[Int] que, dada uma lista de
-- inteiros, retorna uma lista correspondente a original deslocada
-- uma posicao a esquerda.
desloque :: [Int] -> [Int]
desloque [] = []
desloque (h:tail) = tail ++ [h]
-- p4
-- Dado um numero interio, verifique se ele pertence ao
-- intervalo (0,100) e eh divisivel por 3 e por 5
pertence :: Int->[Int] -> Bool
verificar :: Int -> Bool
intervalo :: [Int]
-- Intervalo dos numeros divisiveis por 3 e por 5
intervalo = [0,15..90]
-- Verifica se um numero pertence a uma lista
pertence n [] = False
pertence n (h:tail)
| n == h = True
| n > h = pertence n tail
| otherwise = False
-- Verifica se o numero em questao pertence ao intervalo que eu quero
verificar n = pertence n intervalo
-- pode-se usar a funcao pertence do p2 ou p8, que eh muito mais simples
-- pertence n lista = [ x | x <- lista, x == n ] /= []
-- p7
-- Contrua uma funcao elimina::[Int]->Int->[Int] que, dada uma lista
-- de interiros e um numero inteiro, retorne uma lista onde todas
-- as ocorrencias desse numero foram eliminadas.
elimina :: [Int]->Int->[Int]
elimina [] a = []
elimina (h:tail) a
| h == a = elimina tail a -- Achei, nao concateno
| otherwise = [h] ++ elimina tail a -- Nao achei, concateno
-------------------------------------------------
-- outra versao
elimina2 :: [Int]->Int->[Int]
-- x pertence ao conjunto tal que x != n
elimina2 lista n = [ x | x <- lista, x /= n]
-- p8
-- o que faz o codigo abaixo?
f :: [Int] -> Int -> Bool
f a b = [ x | x <- a, x == b] /= []
-- Verifica se 'b' pertence a lista 'a'
-- p9
-- Defina funcoes para verificar:
-- se uma lista eh sublista de outra e
-- se uma lista eh subsequencia de outra (implica ser sublista)
isSublista :: [Int] -> [Int] -> Bool
isSubseq :: [Int] -> [Int] -> Bool
isInitSeq :: [Int] -> [Int] -> Bool
---------------------------------------------------
-- A primeira lista acabou
isSublista [] lista = True
-- A primeira lista nao acabou, mas a segunda sim.
isSublista lista [] = False
isSublista (h1:t1) (h2:t2)
| h1 == h2 = isSublista t1 t2 -- Verifica se o resto eh sublista
| otherwise = isSublista ([h1] ++ t1) t2 -- ainda procura, mas descarta a cabeca da 2 lista
---------------------------------------------------
-- Verifica primeiro se eh uma sublista (FIXME: isto eh necessario? nao)
--isSubseq lista1 lista2
-- | isSublista lista1 lista2 == False = False
isSubseq [] lista = True
isSubseq lista [] = False
-- Procurar inicio da sequencia
isSubseq (h1:t1) (h2:t2)
-- Achou inicio da possivel sequencia, caso nao seja, ainda eh
-- possivel ter uma subsequencia no resto da cadeia.
| h1 == h2 = isInitSeq t1 t2 || isSubseq ( [h1] ++ t1 ) t2
| otherwise = isSubseq ( [h1] ++ t1 ) t2
isInitSeq [] lista = True
isInitSeq lista [] = False
isInitSeq (h1:t1) (h2:t2)
| h1 == h2 = isInitSeq t1 t2
| otherwise = False
@AtilioA
Copy link

AtilioA commented Apr 22, 2018

haha, olha as perguntas :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment