Add `isPrime` and `divides` to Euler.hs.
This commit is contained in:
parent
39772d8b2b
commit
7d015132e9
33
Euler.hs
33
Euler.hs
|
|
@ -9,9 +9,11 @@ module Euler
|
||||||
, whenM
|
, whenM
|
||||||
, unlessM
|
, unlessM
|
||||||
, primesTo
|
, primesTo
|
||||||
, isPrimeArray
|
, isPrimeArrayTo
|
||||||
, primes
|
, primes
|
||||||
|
, isPrime
|
||||||
, primeFactors
|
, primeFactors
|
||||||
|
, divides
|
||||||
, zipArraysWith
|
, zipArraysWith
|
||||||
, RangeIx(..)
|
, RangeIx(..)
|
||||||
, divisors
|
, divisors
|
||||||
|
|
@ -60,26 +62,30 @@ whenM mc m = mc >>= (\c -> when c m)
|
||||||
unlessM mc m = mc >>= (\c -> unless c m)
|
unlessM mc m = mc >>= (\c -> unless c m)
|
||||||
|
|
||||||
primesTo n = LST.runST $ do
|
primesTo n = LST.runST $ do
|
||||||
isPrime <- LST.strictToLazyST (newArray (2, n) 1 :: ST s (STUArray s Integer Word8))
|
isPrimeArr <- LST.strictToLazyST (newArray (2, n) 1 :: ST s (STUArray s Integer Word8))
|
||||||
let primesFrom m = if m > n then return [] else do
|
let primesFrom m = if m > n then return [] else do
|
||||||
p <- LST.strictToLazyST (readArray isPrime m)
|
p <- LST.strictToLazyST (readArray isPrimeArr m)
|
||||||
if p == 0 then primesFrom (m+1) else do
|
if p == 0 then primesFrom (m+1) else fmap (m:) $ do
|
||||||
LST.strictToLazyST $ forM_ [2*m,3*m..n] $ \i -> writeArray isPrime i 0
|
LST.strictToLazyST $ forM_ [2*m,3*m..n] $ \i -> do
|
||||||
(m:) <$> primesFrom (m+1)
|
writeArray isPrimeArr i 0
|
||||||
|
primesFrom (m+1)
|
||||||
primesFrom 2
|
primesFrom 2
|
||||||
|
|
||||||
isPrimeArray n = runSTUArray $ do
|
isPrimeArrayTo n = runSTUArray $ do
|
||||||
isPrime <- newArray (2, n) 1 :: ST s (STUArray s Integer Word8)
|
isPrimeArr <- newArray (2, n) 1 :: ST s (STUArray s Integer Word8)
|
||||||
forM_ [2..n] $ \m -> whenM ((/= 0) <$> readArray isPrime m) $ do
|
forM_ [2..n] $ \m -> whenM ((/= 0) <$> readArray isPrimeArr m) $ do
|
||||||
forM_ [2*m,3*m..n] $ \i -> writeArray isPrime i 0
|
forM_ [2*m,3*m..n] $ \i -> writeArray isPrimeArr i 0
|
||||||
return isPrime
|
return isPrimeArr
|
||||||
|
|
||||||
primes :: [Integer]
|
primes :: [Integer]
|
||||||
--primes = let go (!p:xs) = p : go [ x | x <- xs, x `mod` p /= 0 ] in go [2..]
|
--primes = let go (!p:xs) = p : go [ x | x <- xs, not (p `divides` x) ] in go [2..]
|
||||||
primes = go 1000000
|
primes = go 1000000
|
||||||
where
|
where
|
||||||
go n = primesTo n ++ dropWhile (<= n) (go (2*n))
|
go n = primesTo n ++ dropWhile (<= n) (go (2*n))
|
||||||
|
|
||||||
|
isPrime :: Integer -> Bool
|
||||||
|
isPrime n = n >= 2 && not (any (`divides` n) $ takeWhile ((<=n).(^2)) primes)
|
||||||
|
|
||||||
primeFactors :: Integer -> [Integer]
|
primeFactors :: Integer -> [Integer]
|
||||||
primeFactors n = go n primes
|
primeFactors n = go n primes
|
||||||
where
|
where
|
||||||
|
|
@ -90,6 +96,9 @@ primeFactors n = go n primes
|
||||||
| (q, 0) <- n `divMod` p = p : go q (p:ps)
|
| (q, 0) <- n `divMod` p = p : go q (p:ps)
|
||||||
| otherwise = go n ps
|
| otherwise = go n ps
|
||||||
|
|
||||||
|
divides :: Integral a => a -> a -> Bool
|
||||||
|
a `divides` b = b `mod` a == 0
|
||||||
|
|
||||||
class Ix a => RangeIx a where
|
class Ix a => RangeIx a where
|
||||||
intersectBounds :: (a, a) -> (a, a) -> (a, a)
|
intersectBounds :: (a, a) -> (a, a) -> (a, a)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,6 @@
|
||||||
|
|
||||||
import Euler
|
import Euler
|
||||||
|
|
||||||
isPrime :: Integer -> Bool
|
|
||||||
isPrime n = n >= 2 && not (any (\p -> n `mod` p == 0) $ takeWhile (< n) primes)
|
|
||||||
|
|
||||||
nPrimes a b = length $ takeWhile isPrime $ map (\n -> n^2 + a*n + b) [0..]
|
nPrimes a b = length $ takeWhile isPrime $ map (\n -> n^2 + a*n + b) [0..]
|
||||||
|
|
||||||
main = print $ uncurry (*) $ snd $ maximumBy (compare `on` fst) $
|
main = print $ uncurry (*) $ snd $ maximumBy (compare `on` fst) $
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,5 @@ rotations n = map (fromDigits . take (length digits))
|
||||||
|
|
||||||
main = do
|
main = do
|
||||||
let limit = 1000000 - 1
|
let limit = 1000000 - 1
|
||||||
let isPrimeArr = isPrimeArray limit
|
|
||||||
let isPrime n = (isPrimeArr!n) /= 0
|
|
||||||
let circular n = all isPrime $ rotations n
|
let circular n = all isPrime $ rotations n
|
||||||
print $ length $ filter circular [2..limit]
|
print $ length $ filter circular [2..limit]
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,4 @@ import Euler
|
||||||
import Data.Array.Unboxed
|
import Data.Array.Unboxed
|
||||||
|
|
||||||
truncations n = map fromDigits $ filter (not . null) $ inits (toDigits n) ++ tails (toDigits n)
|
truncations n = map fromDigits $ filter (not . null) $ inits (toDigits n) ++ tails (toDigits n)
|
||||||
|
|
||||||
isPrimeArr = isPrimeArray 1000000
|
|
||||||
isPrime n = n >= 2 && isPrimeArr!n /= 0
|
|
||||||
|
|
||||||
main = print $ sum $ take 11 $ filter (all isPrime . truncations) [11..]
|
main = print $ sum $ take 11 $ filter (all isPrime . truncations) [11..]
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,4 @@ import Euler
|
||||||
pandigitals = map fromDigits $ go 9
|
pandigitals = map fromDigits $ go 9
|
||||||
where go 0 = []; go n = reverse (sort (permutations [1..n])) ++ go (n-1)
|
where go 0 = []; go n = reverse (sort (permutations [1..n])) ++ go (n-1)
|
||||||
|
|
||||||
isPrime n = not $ any (\p -> n `mod` p == 0) $
|
|
||||||
takeWhile (<= floor (sqrt (fromIntegral n))) primes
|
|
||||||
|
|
||||||
main = print $ head $ filter isPrime pandigitals
|
main = print $ head $ filter isPrime pandigitals
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,6 @@
|
||||||
import Euler
|
import Euler
|
||||||
import Debug.Trace
|
import Debug.Trace
|
||||||
|
|
||||||
isPrime :: Integer -> Bool
|
|
||||||
isPrime n = n >= 2 && all (\p -> n `mod` p /= 0) smallPrimes
|
|
||||||
where smallPrimes = takeWhile (<= floor (sqrt (fromIntegral n))) primes
|
|
||||||
|
|
||||||
main = print $ head $ do
|
main = print $ head $ do
|
||||||
base <- primes
|
base <- primes
|
||||||
let digits = toDigits base
|
let digits = toDigits base
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@ module Main where
|
||||||
|
|
||||||
import Euler
|
import Euler
|
||||||
|
|
||||||
isPrime n = n >= 2 && not (any (\p -> n `mod` p == 0) $ takeWhile ((<= n) . (^2)) primes)
|
|
||||||
|
|
||||||
-- diagonals of an m by m spiral; m = 2*n + 1.
|
-- diagonals of an m by m spiral; m = 2*n + 1.
|
||||||
allDiags = 1 : zipWith (+) allDiags (concat $ map (replicate 4) [2,4..])
|
allDiags = 1 : zipWith (+) allDiags (concat $ map (replicate 4) [2,4..])
|
||||||
allDiags' = map isPrime allDiags
|
allDiags' = map isPrime allDiags
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue