# Paste: PI3-1

Author: Crest haskell 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

-- As are Triangles.
data Triangle = T Point Point Point deriving Show
instance Shape Triangle where
move (T point1 point2 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 =
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')])