You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-- Build prime number table would be much slower than performing prime tests,-- since we check only x and n-x, and in most cases x < 10 (28.7% when n < 20000).goldbach'::Int->Int->Int-> [Int]
goldbach' n m1 m2 =filter (\x -> isPrime x && isPrime (n-x)) $3:5:[6+m1,12+m1..n-2]
where isPrime x =null$filter (\y -> x `mod` y ==0) [2..fsqrt x] -- expect x > 1
fsqrt =floor.sqrt.fromIntegralgoldbach::Int->Maybe (Int, Int)
goldbach 4=Just (2, 2) -- the only case 2 would showed up
goldbach n -- expect n `elem` [4,6..]|null search =Nothing|otherwise=let x =head search inJust (x, n - x)
where search =case n `mod`6of0-> goldbach' n 15-- (6k+1, 6k-1)2-> goldbach' n 11-- (6k+1, 6k+1)4-> goldbach' n 55-- (6k-1, 6k-1)otherwise->[]-- main = print $ map goldbach [4,6..20000] -- takes 0.95 sec
-- FLOLAC 2018 Week 3 -- Goldbach's conjecture-- A simple, intuitive, straight fowward solution.-- And may be not so efficient. :-) goldbach::Int->Maybe (Int, Int)
goldbach nn
| nn <3=Nothing|odd nn =Nothing|otherwise=ifnull pairs
thenNothingelseJust$head pairs
where
pairs = [ (m,n) | m <- tryRange,
n <- tryRange,
(m + n) == nn ]
tryRange =takeWhile (\x -> x < nn) primeList
primeList = ppList [2.. ]
ppList (n : ns) = n : ppList (filter (\x -> (mod x n) /=0 ) ns)
-- Thanks to the call-by-need lazy evaluation,-- The efficiency is really not bad. :-)
goldbach::Int->Maybe (Int, Int)
goldbach n =let ps = [(x, n-x) | x <- [2..(n `div`2)], isPrime x, isPrime (n-x)]
in safeFst ps
where isPrime n =and (map (\x -> n `mod` x /=0) [2..(n-1)])
safeFst []=Nothing
safeFst (x:xs) =Just x
{- Richard Bird's quick algorithm for generating prime numbers. Note that the usual "one-liner" Haskell definition of the sieve is not an honest implementation of the sieve of Eratosthenes. The following algorithm by Bird is a more faithful implementation that is not asymptotically the best, but practically fast enough. Further more, we can reuse the "union" function. For more info see: Melissa E. O’Neill, The genuine sieve of Eratosthenes. Journal of Functional Programming 19(1), 2009.-}primes:: [Int]
primes =2:([3..] `minus` composites)
where composites = unionBy id [multiples p | p <- primes]
multiples n =map (n*) [n..]
(x:xs) `minus` (y:ys) | x < y = x : (xs `minus` (y:ys))
| x == y = xs `minus` ys
| x > y = (x:xs) `minus` ys
-- merging sorted infinite lists of infinite lists.unionBy::Ordb=> (a->b) -> [[a]] -> [a]
unionBy f =foldr merge []where merge (x:xs) ys = x : merge' xs ys
merge' (x:xs) (y:ys) | f x < f y = x : merge' xs (y:ys)
| f x == f y = x : merge' xs ys
| f x > f y = y : merge' (x:xs) ys
-- the main functiongoldbach::Int->Maybe (Int, Int)
goldbach n = check .head.dropWhile ((< n) .uncurry(+)) $ primepairs ()where check (p,q) | p + q == n =Just (p,q)
|otherwise=Nothing-- all pairs of primes, sorted by their sumsprimepairs::()-> [(Int, Int)]
primepairs _ = unionBy (uncurry(+)) (primesMatrix primes)
where primesMatrix (p:ps) =map (\q -> (p, q)) (p:ps) : primesMatrix ps
sieve:: [Int] -> [Int]
sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /=0]
primes:: [Int]
primes = sieve [2..]
goldbachs::Int-> [(Int, Int)]
goldbachs n = [(x, y) | x <- primesSmallerThenHalfOfN, y <- primesSmallerThenN, x < y, x + y == n]
where primesSmallerThenHalfOfN =takeWhile (< n `div`2) primes
primesSmallerThenN =takeWhile (< n) primes
goldbach::Int->Maybe (Int, Int)
goldbach n =casetake1$ goldbachs n of pair:_ ->Just(pair)
otherwise->Nothing