{-
	LISTA 5
	ESDRAS MAYRINK
-}

{----------------------------------IMPLEMENTAÇÃO DA FUNÇÃO MAP	-----------------}

mapy					:: (x->xs) -> [x] -> [xs]
mapy f  []			=  []
mapy f (x:xs)		=  f x : mapy f xs

{----------------------------------IMPLEMENTAÇÃO DA FUNÇÃO FILTER --------------}

myFilter 			::(p->Bool) -> [p] -> [p]
myFilter p [] 		= []
myFilter p (x:xs)
	| p x				= x : myFilter p xs
	| otherwise		= myFilter p xs
	
{----------------------------------IMPLEMENTAÇÃO DA FUNÇÃO FOLDL --------------}

myFoldl :: (x->x->x) -> [x] -> x
myFoldl f [x] = x
myFoldl f (x:xs:ys) = f x (myFoldl f (xs:ys))

{----------------------------------IMPLEMENTAÇÃO TRIÂNGULO PASCAL -------------}

-- calculo fatorial...---------------------------------------
--ficar ligado pq n > 13 produz resultados inconsistentes
--excedendo o limite suportado por Int

nFatorial :: Int -> Int
nFatorial 0 = 1
nFatorial n = n * nFatorial (n-1)

-- função que retorna o binômio de newton

biNewton :: 	Int -> Int -> Int
biNewton n k
	| (n < k) 	= biNewton k n
	| otherwise = ((nFatorial n)`div`((nFatorial k)*(nFatorial (n-k))))


-- função q retorna uma lista para a aplicação do binômio de newton
makeList ::	Int -> [Int]
makeList n 	= (n-1) : [(n-2), (n-3) .. 0]

-- função q aplica o biNewton em uma linha n e nas respectivas colunas ( [n .. 0] )
aplyBiNewton :: Int -> [Int] -> [Int]
aplyBiNewton n [] = []
aplyBiNewton n (x:xs) = biNewton n x : aplyBiNewton n xs

------------------------------------------------------------------------------
--funções para ordenar e mostrar a lista como o exercício pediu				---
																									---
insere :: [Int] -> [[Int]] -> [[Int]]													---
insere x [] = [x]																				---
insere x (y:z)																					---
	| ((myFoldl (+) x) < (myFoldl (+) y)) 	= x:y:z									---
	| otherwise 									= y : insere x z						---
																									---
ordena :: [[Int]] -> [[Int]]																---
ordena [] = []																					---
ordena (x:xs) = insere x (ordena xs)													---
------------------------------------------------------------------------------

---************FUNÇÃO TRIPASCAL FINAL************
triPascal :: Int -> [[Int]]
triPascal 1 = [(aplyBiNewton 0 [0])]
triPascal n = ordena ((aplyBiNewton (n-1) (makeList n)) : triPascal (n-1))

{----------------------------------IMPLEMENTAÇÃO TORRE HANÓI -------------}

-- [discos] -> torreInicial -> torreAuxiliar -> torreFinal



