fork download
  1. import Control.Monad
  2. import Control.Monad.ST
  3. import Data.Array.ST
  4. import Data.Maybe
  5.  
  6. data Primality
  7. = Prime
  8. | OneFactor Integer
  9. | TwoFactor Integer Integer
  10. | ManyFactor
  11. deriving (Eq, Ord, Read, Show)
  12.  
  13. addFactor :: Integer -> Primality -> Primality
  14. addFactor f Prime = OneFactor f
  15. addFactor f (OneFactor f') = TwoFactor f f'
  16. addFactor _ _ = ManyFactor
  17.  
  18. isSemiprime :: Integer -> Primality -> Bool
  19. isSemiprime n (OneFactor f ) = f * f == n
  20. isSemiprime n (TwoFactor f f') = f * f' == n
  21. isSemiprime _ _ = False
  22.  
  23. nextSemiprime :: Integer -> Integer
  24. nextSemiprime n = runST $ do
  25. arr <- newSTArray (2,2*n) Prime
  26. forM_ [2..n] $ \p -> do
  27. primality <- readArray arr p
  28. when (primality == Prime) $
  29. forM_ [2*p,3*p..2*n] $ \i ->
  30. modifyArray arr i (addFactor p)
  31. -- going up to 2*n is big enough by Bertrand's postulate
  32. fromJust <$> findM (\i -> isSemiprime i <$> readArray arr i) [n+1..2*n]
  33.  
  34. findM :: Monad m => (a -> m Bool) -> [a] -> m (Maybe a)
  35. findM f [] = return Nothing
  36. findM f (x:xs) = do
  37. done <- f x
  38. if done then return (Just x) else findM f xs
  39.  
  40. modifyArray :: (MArray a e m, Ix i) => a i e -> i -> (e -> e) -> m ()
  41. modifyArray arr ix f = readArray arr ix >>= writeArray arr ix . f
  42.  
  43. -- just to fix the type
  44. newSTArray :: Ix i => (i,i) -> e -> ST s (STArray s i e)
  45. newSTArray = newArray
  46.  
  47. main = print . take 100 . iterate nextSemiprime $ 4
Success #stdin #stdout 0s 8388607KB
stdin
Standard input is empty
stdout
[4,6,9,10,14,15,21,22,25,26,33,34,35,38,39,46,49,51,55,57,58,62,65,69,74,77,82,85,86,87,91,93,94,95,106,111,115,118,119,121,122,123,129,133,134,141,142,143,145,146,155,158,159,161,166,169,177,178,183,185,187,194,201,202,203,205,206,209,213,214,215,217,218,219,221,226,235,237,247,249,253,254,259,262,265,267,274,278,287,289,291,295,298,299,301,302,303,305,309,314]