fork download
  1. -- programming with prime numbers
  2.  
  3. import Control.Monad (forM_, when)
  4. import Control.Monad.ST
  5. import Data.Array.ST
  6. import Data.Array.Unboxed
  7. import Data.List (sort)
  8.  
  9. sieve :: Int -> UArray Int Bool
  10. sieve n = runSTUArray $ do
  11. let m = (n-1) `div` 2
  12. bits <- newArray (0, m-1) True
  13. forM_ [0 .. r `div` 2 - 1] $ \i -> do
  14. isPrime <- readArray bits i
  15. when isPrime $ do
  16. forM_ [2*i*i+6*i+3, 2*i*i+8*i+6 .. (m-1)] $ \j -> do
  17. writeArray bits j False
  18. return bits
  19.  
  20. primes :: Int -> [Int]
  21. primes n = 2 : [2*i+3 | (i, True) <- assocs $ sieve n]
  22.  
  23. tdPrime :: Int -> Bool
  24. tdPrime n = prime (2:[3,5..])
  25. where prime (d:ds)
  26. | n < d * d = True
  27. | n `mod` d == 0 = False
  28. | otherwise = prime ds
  29.  
  30. tdFactors :: Int -> [Int]
  31. tdFactors n = facts n (2:[3,5..])
  32. where facts n (f:fs)
  33. | n < f * f = [n]
  34. | n `mod` f == 0 = f : facts (n `div` f) (f:fs)
  35. | otherwise = facts n fs
  36.  
  37. powmod :: Integer -> Integer -> Integer -> Integer
  38. powmod b e m =
  39. let times p q = (p*q) `mod` m
  40. pow b e x
  41. | e == 0 = x
  42. | even e = pow (times b b) (e `div` 2) x
  43. | otherwise = pow (times b b) (e `div` 2) (times b x)
  44. in pow b e 1
  45.  
  46. isSpsp :: Integer -> Integer -> Bool
  47. isSpsp n a =
  48. let getDandS d s =
  49. if even d then getDandS (d `div` 2) (s+1) else (d, s)
  50. spsp (d, s) =
  51. let t = powmod a d n
  52. in if t == 1 then True else doSpsp t s
  53. doSpsp t s
  54. | s == 0 = False
  55. | t == (n-1) = True
  56. | otherwise = doSpsp ((t*t) `mod` n) (s-1)
  57. in spsp $ getDandS (n-1) 0
  58.  
  59. isPrime :: Integer -> Bool
  60. isPrime n =
  61. let ps = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
  62. in n `elem` ps || all (isSpsp n) ps
  63.  
  64. rhoFactor :: Integer -> Integer -> Integer
  65. rhoFactor n c =
  66. let f x = (x*x+c) `mod` n
  67. fact t h
  68. | d == 1 = fact t' h'
  69. | d == n = rhoFactor n (c+1)
  70. | isPrime d = d
  71. | otherwise = rhoFactor d (c+1)
  72. where
  73. t' = f t
  74. h' = f (f h)
  75. d = gcd (t' - h') n
  76. in fact 2 2
  77.  
  78. rhoFactors :: Integer -> [Integer]
  79. rhoFactors n =
  80. let facts n
  81. | n == 2 = [2]
  82. | even n = 2 : facts (n `div` 2)
  83. | isPrime n = [n]
  84. | otherwise = let f = rhoFactor n 1
  85. in f : facts (n `div` f)
  86. in sort $ facts n
  87.  
  88. main = do
  89. print $ primes 100
  90. print $ length $ primes 1000000
  91. print $ tdPrime 716151937
  92. print $ tdFactors 8051
  93. print $ powmod 437 13 1741
  94. print $ isSpsp 2047 2
  95. print $ isPrime 600851475143
  96. print $ isPrime 2305843009213693951
  97. print $ rhoFactors 600851475143
Success #stdin #stdout 0.04s 4644KB
stdin
Standard input is empty
stdout
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
78498
False
[83,97]
819
True
False
True
[71,839,1471,6857]