Chowla numbers: Difference between revisions

m
→‎{{header|Haskell}}: use STM TChan vs Chan. Significant performance improvement.
m (→‎{{header|Haskell}}: use STM TChan vs Chan. Significant performance improvement.)
Line 1,520:
Uses arithmoi Library: https://hackage.haskell.org/package/arithmoi-0.11.0.0
compiled with "-O2 -threaded -rtsopts"<br/>
<lang haskell>import Control.Concurrent (setNumCapabilities, forkIO)
import Control.MonadConcurrent.ParSTM (TChan, readTChan, (runParwriteTChan, getatomically, spawnP)
import Control.Monad (join, (>=>) newTChan,)
import Control.Monad (forever, replicateM_, replicateM)
import Data.List.Split (chunksOf)
import Data.List (intercalate, mapAccumL, genericTake, genericDrop)
Line 1,536 ⟶ 1,537:
f = (-) =<< pred . product . fmap sumFactor . factorise
sumFactor (n, e) = foldr (\p s -> s + unPrime n^p) 1 [1..e]
 
chowlas :: [Word] -> [(Word, Word)]
chowlas [] = []
chowlas xs = runPar $ join <$>
(mapM (spawnP . fmap ((,) <*> chowla)) >=> mapM get) (chunksOf (10^6) xs)
 
chowlaPrimes :: [(Word, Word)] -> (Word, Word) -> (Word, Word)
Line 1,552 ⟶ 1,548:
chowlaPerfects :: [(Word, Word)] -> [Word]
chowlaPerfects = fmap fst . filter isPerfect
where
isPerfect (1, _) = False
isPerfect (n, c) = c == pred n
Line 1,558 ⟶ 1,554:
commas :: (Show a, Integral a) => a -> String
commas = reverse . intercalate "," . chunksOf 3 . reverse . show
 
chowlaschowlaWorker :: [TChan Word] -> [TChan (Word, Word)] -> IO ()
chowlaWorker input output = forever (atomically (readTChan input) >>=
atomically . writeTChan output . ((,) <*> chowla))
 
main :: IO ()
Line 1,564:
setNumCapabilities cores
printf "Using %d cores\n" cores
 
allChowlas <- parallelChowlas cores
 
mapM_ (uncurry (printf "chowla(%2d) = %d\n")) $ take 37 allChowlas
mapM_ (uncurry (printf "There are %8s primes < %10s\n"))
(chowlaP allChowlas
[ (1, 10^2)
, (succ $ 10^2, 10^3)
Line 1,575 ⟶ 1,577:
, (succ $ 10^6, 10^7) ])
 
let perfects = chowlaPerfects allChowlas
mapM_ (printf "%10s is a perfect number.\n" . commas) perfects
printf "There are %2d perfect numbers < 35,000,000\n" $ length perfects
where
chowlaP xs = fmap (bimap commas commas) . snd
. mapAccumL (\total (count, max) -> (total + count, (total + count, max))) 0
. fmap (chowlaPrimes $ take (10^7) allChowlasxs)
 
perfects = chowlaPerfects allChowlas
parallelChowlas cores = do
allChowlas = chowlas [1..35*10^6]</lang>
inputChan <- atomically newTChan
outputChan <- atomically newTChan
replicateM_ cores (forkIO $ chowlaWorker inputChan outputChan)
mapM_ (atomically . writeTChan inputChan) [1..35*10^6]
replicateM (35*10^5) (atomically (readTChan outputChan))</lang>
{{out}}
<pre>Using 4 cores
Anonymous user