Paste: PI3-1

Author: Crest
Mode: haskell
Date: Mon, 10 Nov 2008 20:35:44
Plain Text |
-- Approximate the square root of $x to at least the accuracy of $eps
-- collecting the steps in a list.
squareRoot :: Double -> Double -> [Double]
squareRoot x eps | x   < 0.0 = error "Non real answer."
                 | eps < 0.0 = error "Accuracy can't be more than perfect."
		 | otherwise = loop [((1 + x) / 2)] where
	loop :: [Double] -> [Double]
	loop (y:t) | abs((y * y) - x) <= eps = y : t
	           | otherwise               = loop ((0.5*(y+(x/y))):y:t)


-- Just the head of this list.
-- I wonder if the compiler is capeable to optimize the list away ...
wurzel :: Double -> Double -> Double
wurzel x eps = head (squareRoot x eps)


-- How many approximations does it take to reach $eps accuracy
count :: Double -> Double -> Int
count x eps = length (squareRoot x eps)


sq :: Double -> Double
sq x = x * x

-- Trivial isn't it?
data Point = P Double Double deriving Show


add :: Point -> Point -> Point
add (P x1 y1) (P x2 y2) = P (x1+x2) (y1+y2)


distance :: Point -> Point -> Double
distance (P x1 y1) (P x2 y2) = sqrt ((sq (x1 - x2)) + (sq (y1 - y2)))


-- A shape has an area an can be moved.
class Shape a where 
	move :: a -> Point -> a
	area :: a -> Double


-- Circles are shapes.
data Circle = C Point Double deriving Show
instance Shape Circle where
	move (C middle radius) delta = C (add middle delta) radius
	area (C middle radius)       = pi * (sq radius)


-- As are Triangles.
data Triangle = T Point Point Point deriving Show
instance Shape Triangle where
	move (T point1 point2 point3) delta =
		T (add point1 delta) (add point2 delta) (add point3 delta)
	area (T point1 point2 point3) =
		sqrt (s * (s - a) * (s - b) * (s - c)) where
			s = (a + b + c) / 2
			a = distance point1 point2
			b = distance point2 point3
			c = distance point3 point1


-- and Rectangles.
data Rectangle = R Point Point deriving Show
instance Shape Rectangle where
	move (R p1 p2) d =
		R (add p1 d) (add p2 d)
	area (R (P x1 y1) (P x2 y2)) =
		abs((x1 - x2) * (x1 - y2))


-- Bits are Zero or One.
data Bit = Zero | One deriving (Eq, Show)


-- Encode an Int as a Bit.
enc1 :: Int -> Bit
enc1 x | x == 0 = Zero
       | x /= 0 = One


-- Decode a Bit to an Int.
dec1 :: Bit -> Int
dec1 x | x == Zero = 0
       | x == One  = 1

-- Convert from one datatype to an other by replaceing
-- occurances of x with occurances y.
replace :: (Eq a) => [(a,b)] -> a -> b
replace [ ] _                       = error "Undefined replacement"
replace ((a, b) : xs) x | a == x    = b
		        | otherwise = replace xs x


-- Pretty selfexplaining isn't it?
encode :: Int -> [Bit]
encode n | n <  0    = error "Can't convert negative numbers."
         | otherwise = convert n [] where
	convert :: Int -> [Bit] -> [Bit]
	convert 0 l = l
	convert n l = convert (floor (fromIntegral n / 2))
	                      ((enc1 (mod n 2)):l)

decode :: [Bit] -> Int
decode l = foldl (\sum bit -> 2 * sum + (dec1 bit)) 0 l

display :: [Bit] -> String
display = map (replace [(Zero, '0'), (One, '1')])

New Annotation

Summary:
Author:
Mode:
Body: