-------------------------------
-- Lista 5 ------------ LPG3 --
-- Felipe Gallois            --
--                           --
-------------------------------

-- 1
map1 a [] = []
map1 a (x:xs) = (a x):map1 a xs

-- funcao auxiliar
maior_q_5 x
	| x > 5 = True
	| otherwise = False

-- 2
filter1 a [] = []
filter1 a (x:xs)
	| a x == True = x:filter1 a xs
	| otherwise = filter1 a xs

-- funcao auxiliar
soma x y = x + y

-- 3
foldl2 a b [c] = a b c
foldl2 a b (x:xs) = a b (foldl2 a x xs)

-- funcao auxiliar para calcular as linhas do triangulo de Pascal
-- retorna cada uma das linhas
linhaTriangulo :: Float -> [Integer]
linhaTriangulo x = map round (linhaTriangulo' x y y)
	where 
		y = 1;
		linhaTriangulo' :: Float -> Float -> Float -> [Float]
		linhaTriangulo' x y z
			| x == 0 = [1]
			| x == 1 = [1, 1]
			| rc == 1 = [1]
			| y == 1 = 1:h:linhaTriangulo' x (y+1) h
			| otherwise = h:linhaTriangulo' x (y+1) h
				where 
					h  = (z * (rc/c));
					rc = r - c;
					r = x + 1; 
					c = y;

-- 4
trianguloPascal :: Float -> [[Integer]]
trianguloPascal 0 = [[1]]
trianguloPascal x = trianguloPascal (x-1) ++ [linhaTriangulo x]

-- 5
-- f eh o pino de origem, t o de destino e r o auxiliar
hanoi :: [Integer] -> Integer -> Integer -> Integer ->  IO()
hanoi [] _ _ _ = print "Nao existem discos"
hanoi (x:xs) f t r 
	| length (x:xs) == 1 = putStrLn ("Move " ++ show x ++ " de " ++ show f ++ " para " ++ show t)
	| otherwise = do
		hanoi xs f r t
		putStrLn ("Move " ++ show x ++ " de " ++ show f ++ " para " ++ show t)
		hanoi xs r t f
