-------------HASCKELL------------
--		Esdras Mayrink 			---
--		Júlio Santos Monteiro	---
--										---
--				LISTA4				---
--										---
---------------------------------

--EXE 1-----------------------------------------------------------

-- função q limita o argumento entre 0 e 9

chkIn :: Int -> Bool
chkIn x = (x >= 0 && x <= 9)

-- função que preenche a lista
insereLista :: Int -> [Int]
insereLista x
	| (x + 10 <= 100) = x : insereLista(x+10)
	| otherwise 		= x : []

-- função de saída ( resultado final )
termina_em :: Int -> String
termina_em x
	| (chkIn x) = show(insereLista x)
	| otherwise = "Insira um argumento valido: [0,9]"


--EXE 2-----------------------------------------------------------

contaElem :: Int -> [Int] -> Int
contaElem e [] = 0
contaElem e (x:y)
	| (e == x) 	= 1 + contaElem e y
	| otherwise = contaElem e y

--EXE 3-----------------------------------------------------------

-- função auxiliar que preenche ordenadamente

fillList :: Int -> [Int] -> [Int]
fillList e [] = [e]
fillList e (x:y)
	| (e <= x) = e:(x:y)
	|otherwise = x : fillList e y

-- função que exibe o resultado
ordenaLista :: [Int] -> [Int]
ordenaLista [] 	= []
ordenaLista (x:y) = fillList x (ordenaLista y)

--EXE 4-----------------------------------------------------------

getMultiplos x (a,b)
	| a == b = []
	| a > b = getMultiplos x (b,a)
	| x == 0 = []
	| x == 1 = [a..b]
	| otherwise = filter (\e -> (e `mod` x == 0)) [a..b]

--EXE 5-----------------------------------------------------------

removeElem :: Int -> [Int] -> [Int]
removeElem e [] = []
removeElem e (x:y)
	| (e /= x) 	= x : removeElem e y
	| otherwise = removeElem e y

--EXE 6-----------------------------------------------------------

insereNaPos :: Int -> Int -> [Int] -> [Int]
insereNaPos e p [] = [e]
insereNaPos e p (x:y)
	| ((p-1) == 0)	= e:x:y
	| otherwise = x : insereNaPos e (p-1) y

--EXE 7-----------------------------------------------------------

noRepeat :: [Int] -> [Int]
noRepeat [] = []
noRepeat (x:[]) = [x]
noRepeat (x:y) = x : removeElem x (noRepeat y)

--EXE 8-----------------------------------------------------------

--função que separa e retorna a primeira parte da lista

primeira :: Int -> [Int] -> [Int]
primeira p (x:y)
	| ((p-1) >= 0)	= x : (primeira (p-1) y)
	| otherwise		= []

--função que separa e retorna a primeira parte da lista

segunda :: Int -> [Int] -> [Int]
segunda p [] = []
segunda p (x:y)
	| ((p-1) < 0)	= x : (segunda (p-1) y)
	| otherwise		= segunda (p-1) y

--função que junta a lista rotacionada

merge :: [Int] -> [Int] -> [Int]
merge [] [] 		= []
merge [] (x:y) 	= (x:y)
merge (a:b) [] 	= (a:b)
merge (a:b) (x:y) = a : (merge b (x:y))

--função que faz a rotação
rotate :: Int -> [Int] -> [Int]
rotate p [] = []
rotate 0 (x:y) = (x:y)
rotate p (x:y) = merge (segunda p (x:y)) (primeira p (x:y))
