import Data.Array.ST data Primality = Prime | OneFactor Integer | ManyFactor addFactor f Prime = OneFactor f addFactor f (OneFactor f') = TwoFactor f f' addFactor _ _ = ManyFactor isSemiprime n (OneFactor f ) = f * f == n isSemiprime n (TwoFactor f f') = f * f' == n isSemiprime _ _ = False nextSemiprime n = runST $ do arr <- newSTArray (2,2*n) Prime forM_ [2..n] $ \p -> do primality <- readArray arr p when (primality == Prime) $ forM_ [2*p,3*p..2*n] $ \i -> modifyArray arr i (addFactor p) -- going up to 2*n is big enough by Bertrand's postulate fromJust <$> findM (\i -> isSemiprime i <$> readArray arr i) [n+1..2*n] findM f (x:xs) = do done <- f x modifyArray :: (MArray a e m, Ix i) => a i e -> i -> (e -> e) -> m () modifyArray arr ix f = readArray arr ix >>= writeArray arr ix . f -- just to fix the type newSTArray :: Ix i => (i,i) -> e -> ST s (STArray s i e) newSTArray = newArray
Standard input is empty
[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]