Guest User

Untitled

a guest
Aug 8th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ---------------------
  2. -- Timing function --
  3. ---------------------
  4. import Text.Printf
  5. import System.CPUTime
  6.  
  7. timeIO :: IO t -> IO t
  8. timeIO y = do
  9.     start <- getCPUTime
  10.     x     <- y
  11.     end   <- getCPUTime
  12.     let diff = (fromIntegral (end - start)) / (10^12)
  13.     printf "Computation time: %0.3f sec\n" (diff :: Double)
  14.     return x
  15.  
  16. time :: (Show t) => t -> IO ()
  17. time x = do
  18.     timeIO $ do
  19.         r <- return x
  20.         printf "%s\n" $ show r
  21.         return r
  22.     return ()
  23.  
  24. ----------------------
  25. -- Function library --
  26. ----------------------
  27.  
  28. ceilSqrt :: Integral a => a -> a
  29. ceilSqrt = ceiling . sqrt . fromIntegral
  30.  
  31. fibs :: Integral a => [a]
  32. fibs = map fst $ iterate (\(a,b) -> (b,a+b)) (0,1)
  33.  
  34. fib :: Integral a => Int -> a
  35. fib n = fibs !! n
  36.  
  37. ------------
  38. -- Primes --
  39. ------------
  40.  
  41. is_prime :: Integral a => a -> Bool
  42. is_prime 2 = True -- 2 will divide by itself in the generic test; 3+ are fine
  43. is_prime n = foldl (\acc x -> if n `mod` x == 0 then False else acc) True $ takeWhile (<= ceilSqrt n) (2:[3,5..])
  44.  
  45. prime_sieve :: Integral a => [a]
  46. prime_sieve = filter is_prime [2..]
  47.  
  48. prime_divisors :: Integral a => a -> [a]
  49. prime_divisors x =
  50.     let y = map fst $ filter ((==0) . snd) $              -- get all numbers which divide x exactly
  51.             takeWhile ((<= ceilSqrt x) . fst) $           -- for values up to sqrt x
  52.             zip prime_sieve $ (map (mod x) $ prime_sieve) -- that are prime
  53.     in y ++ if is_prime x then [x] else []                -- and also add x to the list if x is prime
  54.  
  55. factors :: Integral a => a -> [a]
  56. factors 1 = []
  57. factors x = let y = head $ prime_divisors x -- get the smallest prime divisor
  58.             in y:factors (x `div` y)        -- use that divisor and append factor x `div` divisor
  59.  
  60. -- Function Library End
  61.  
  62. euler01 = let
  63.     threes = [3,6..999]
  64.     fives  = [5,10..999]
  65.     dupes  = [ x | x <- threes, y <- fives, x == y ]
  66.     in sum [ sum threes, sum fives, 0 - (sum dupes) ]
  67.  
  68. euler02 = sum $ filter even $ takeWhile (<4000000) fibs
  69.  
  70. euler03 = last $ factors 600851475143
  71.  
  72. -- NOTE: VERY VERY SLOW
  73. euler05 = let
  74.     div_test d n = foldl (\acc x -> if n `mod` x /= 0 then False else acc) True [d,d-1..((d + 1) `div` 2)]
  75.     in fst $ head $ filter snd $ zip [1..] $ map (div_test 20) [1..]
Add Comment
Please, Sign In to add comment