Advertisement
Perryman

Kershaw prime sieve

Apr 10th, 2024
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {-# LANGUAGE BangPatterns #-}
  2.  
  3. import Control.Concurrent.Async (mapConcurrently_)
  4. import Control.Concurrent.STM
  5. import Control.Monad (forM_, when)
  6. import qualified Data.IntMap.Strict as IntMap
  7. import Math.NumberTheory.Primes.Testing (isPrime)
  8. import System.Environment (getArgs)
  9.  
  10. kershawPrime :: Int -> Maybe Integer
  11. kershawPrime y = let p = gcd (2 ^ y - 2) (3 ^ y - 2)
  12.                  in if isPrime p then Just p else Nothing
  13.  
  14. processNumber :: TVar (IntMap.IntMap [Int]) -> TVar Int -> Int -> Int -> Int -> IO ()
  15. processNumber primesVar progressVar total start y = do
  16.     maybePrime <- atomically $ do
  17.         modifyTVar' progressVar (+1)
  18.        progress <- readTVar progressVar
  19.        let percentProgress = ((progress * 100) `div` total)
  20.        return (kershawPrime y, percentProgress)
  21.  
  22.    case maybePrime of
  23.        (Just p, percentProgress) -> do
  24.            isNewPrime <- atomically $ do
  25.                primes <- readTVar primesVar
  26.                if IntMap.member (fromIntegral p) primes
  27.                then return False
  28.                else do
  29.                    modifyTVar' primesVar (IntMap.insertWith (++) (fromIntegral p) [y])
  30.                     return True
  31.             when isNewPrime $ putStrLn $ "First found Kershaw prime " ++ show p ++ " at y=" ++ show y
  32.             when (y == start + ((percentProgress * total) `div` 100)) $ putStrLn $ "Now at y=" ++ show y
  33.         (_, percentProgress) ->
  34.             when (y == start + ((percentProgress * total) `div` 100)) $ putStrLn $ "Now at y=" ++ show y
  35.  
  36. findKershawPrimesConcurrently :: Int -> Int -> IO ()
  37. findKershawPrimesConcurrently start end = do
  38.   progressVar <- newTVarIO 0
  39.   primesVar <- newTVarIO IntMap.empty
  40.   let total = end - start + 1
  41.  
  42.   mapConcurrently_ (processNumber primesVar progressVar total start) [start..end]
  43.  
  44.   uniquePrimes <- atomically $ readTVar primesVar
  45.  
  46.   putStrLn "Unique Kershaw primes found:"
  47.   forM_ (IntMap.toList uniquePrimes) $ \(p, ys) ->
  48.     putStrLn $ "Found Kershaw prime " ++ show p ++ " at ys=" ++ show (map (\y -> "y=" ++ show y) ys)
  49.  
  50. main :: IO ()
  51. main = do
  52.   [startStr, endStr] <- getArgs
  53.   let start = read startStr
  54.       end = read endStr
  55.   putStrLn $ "Finding Kershaw primes from " ++ show start ++ " to " ++ show end
  56.   findKershawPrimesConcurrently start end
  57.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement