-- COMP1100 Sem 1, 2006
-- Laboratory Week 3 Solutions
-- Clem Baker-Finch

-----------------------------------------------------------------------
-- Exercise 1:

-- The area of a triangle using this formula neatly suggests a where
-- clause.

-- The area of a triangle can be calculated from the length of its
-- sides a, b, c:

triangleArea :: Float -> Float -> Float -> Float
triangleArea a b c
    = sqrt (s*(s-a)*(s-b)*(s-c))
    where s = (a+b+c)/2

-----------------------------------------------------------------------
-- Exercise 2:

-- Take three integers and test whether any one is the sum of the
-- other two.

isSum :: Int -> Int -> Int -> Bool
isSum x y z
    | x+y == z   = True
    | x+z == y   = True
    | y+z == x   = True
    | otherwise  = False

-- There are plenty of other ways, but this is straightforward and
-- readable.

-----------------------------------------------------------------------
-- Exercise 4:

-- Here is the roots function from lectures, for direct reference:

roots :: Float -> Float -> Float -> (Float, Float)
roots a b c
    | discriminant >= 0  = ((-b + (sqrt discriminant))/(2*a), 
                            (-b - (sqrt discriminant))/(2*a))
    | otherwise          = error "No real roots"
    where discriminant = b^2 - 4*a*c

-- Define a function to check that a triangle exists
-- If any two of the sides have a total length than the third,
-- no triangle exists.
-- Here's an easy approach based on isSum

validTriangle :: Float -> Float -> Float -> Bool
validTriangle a b c
    | a+b < c   = False
    | a+c < b   = False
    | b+c < a   = False
    | otherwise = True

-- Calculate the triangle's area, but return an error message if the
-- sides don't form a triangle

triangleArea' :: Float -> Float -> Float -> Float
triangleArea' a b c
    | validTriangle a b c  = sqrt (s*(s-a)*(s-b)*(s-c))
    | otherwise            = error "Not a triangle"
    where s = (a+b+c)/2

