module HL01GS where -- | 2 divides into 4 -- >>> divides 2 4 -- True -- | 3 does not divide into 4 -- >>> divides 3 4 -- False divides :: Integer -> Integer -> Bool divides d n = rem n d == 0 -- | The least divisor of 12 is 2 -- >>> ld 12 -- 2 -- | The least divisor of 15 is 3 -- >>> ld 15 -- 3 ld :: Integer -> Integer ld n = ldf 2 n -- | The least divisor, from 3 up, of 64 is 4 -- >>> ldf 3 64 -- 4 ldf :: Integer -> Integer -> Integer ldf k n | divides k n = k | n < k ^ 2 = n | otherwise = ldf (k + 1) n -- | 7 is prime -- >>> prime0 7 -- True -- | 6 is not prime -- >>> prime0 6 -- False prime0 :: Integer -> Bool prime0 n | n < 1 = error "not a positive integer" | n == 1 = False | otherwise = ld n == n -- | The minimum of [5, 3, 1, 6] is 1 -- >>> mnmInt [5, 3, 1, 6] -- 1 mnmInt :: [Int] -> Int mnmInt [] = error "empty list" mnmInt [x] = x mnmInt (x : xs) = min x (mnmInt xs) -- min is provided in Prelude, min' is home-made. -- | The minimum of 7 and 5 is 5 -- >>> min 7 5 -- 5 min' :: Int -> Int -> Int min' x y | x <= y = x | otherwise = y -- | The average of [5, 3, 1, 6] is 1 -- >>> average [5, 3, 1, 6] -- 15 % 4 average :: [Int] -> Rational average [] = error "empty list" average xs = toRational (sum xs) / toRational (length xs) -- | The sum of [5, 3, 1, 6] is 15 -- >>> sum' [5, 3, 1, 6] -- 15 sum' :: [Int] -> Int sum' [] = 0 sum' (x : xs) = x + sum' xs -- | The length of [5, 3, 1, 6] is 4 -- >>> length [5, 3, 1, 6] -- 4 length' :: [a] -> Int length' [] = 0 length' (x : xs) = 1 + length' xs -- | Pre is a prefix of Prefix -- >>> prefix "Pre" "Prefix" -- True -- | fix is not a prefix of Prefix -- >>> prefix "fix" "Prefix" -- False prefix :: String -> String -> Bool prefix [] ys = True prefix (x : xs) [] = False prefix (x : xs) (y : ys) = (x == y) && prefix xs ys -- | The prime factors of 66 are [2,3,11] -- >>> factors 66 -- [2,3,11] factors :: Integer -> [Integer] factors n | n < 1 = error "argument not positive" | n == 1 = [] | otherwise = p : factors (div n p) where p = ld n -- | The prime factors of 66 are [2,3,11] -- >>> factors' 66 -- [2,3,11] -- This is just a version using let instead of where. factors' :: Integer -> [Integer] factors' n | n < 1 = error "argument not positive" | n == 1 = [] | otherwise = let p = ld n in p : factors' (div n p) -- | This is an infinite generator of primes, so only take 5 -- >>> take 5 primes0 -- [2,3,5,7,11] primes0 :: [Integer] primes0 = filter prime0 [2 ..] -- | This is an improved least divisor function, only checking primes. -- >>> ldp 15 -- 3 ldp :: Integer -> Integer ldp n = ldpf primes1 n -- | This is similar to ldf above, but faster. -- >>> ldpf [2,3,5,7] 64 -- 2 ldpf :: [Integer] -> Integer -> Integer ldpf (p : ps) n | rem n p == 0 = p | n < p ^ 2 = n | otherwise = ldpf ps n -- | This is a faster version of primes0. -- >>> take 5 primes0 -- [2,3,5,7,11] primes1 :: [Integer] primes1 = 2 : filter prime [3 ..] -- | This is a faster version of prime0 -- >>> prime 7 -- True prime :: Integer -> Bool prime n | n < 1 = error "not a positive integer" | n == 1 = False | otherwise = ldp n == n a = 3 b = 4 -- | f is a function that takes the sum of squares of x and y -- >>> f 4 5 -- 41 f :: Integer -> Integer -> Integer f x y = x ^ 2 + y ^ 2 -- | g of 0 is 1 -- >>> g 0 -- 1 -- | g of anything else is a function of x -- >>> g 5 -- 32 g :: Integer -> Integer g 0 = 1 g x = 2 * g (x - 1) -- | h1 of 0 is 0 -- >>> h1 0 -- 0 -- h1 of anything els has a problem. Ask class what it is. h1 :: Integer -> Integer h1 0 = 0 h1 x = 2 * h1 x -- | h2 of 0 is 0 -- >>> h2 0 -- 0 -- h2 of anything else has a problem too. h2 :: Integer -> Integer h2 0 = 0 h2 x = h2 (x + 1)