module Solutions.P31 (isPrime, isPrime', isPrime'') where
import Solutions.Arithmetic
isPrime :: Integral a => a -> Bool
isPrime :: forall a. Integral a => a -> Bool
isPrime a
n
| a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
2 = Bool
True
| a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
2 = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (a
n `dividesBy`) ([a] -> Bool) -> [a] -> Bool
forall a b. (a -> b) -> a -> b
$ a
2 a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
odds
| Bool
otherwise = Bool
False
where odds :: [a]
odds = (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (\a
k -> a
ka -> a -> a
forall a. Num a => a -> a -> a
*a
k a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
n) ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate (a
2+) a
3
isPrime' :: Integral a => a -> Bool
isPrime' :: forall a. Integral a => a -> Bool
isPrime' a
n
| a
n a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
2 = Bool
True
| a -> Bool
forall a. Integral a => a -> Bool
even a
n = Bool
False
| a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
2 = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (a
n `dividesBy`) [a]
ps
| Bool
otherwise = Bool
False
where ps :: [a]
ps = [a] -> [a]
forall a. Integral a => [a] -> [a]
sieve ((a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (\a
k -> a
ka -> a -> a
forall a. Num a => a -> a -> a
*a
k a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
n) ([a] -> [a]) -> [a] -> [a]
forall a b. (a -> b) -> a -> b
$ (a -> a) -> a -> [a]
forall a. (a -> a) -> a -> [a]
iterate (a
2+) a
3)
sieve :: Integral a => [a] -> [a]
sieve :: forall a. Integral a => [a] -> [a]
sieve [] = []
sieve (a
n:[a]
ns) = a
n a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a] -> [a]
forall a. Integral a => [a] -> [a]
sieve ((a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (a -> Bool) -> a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a -> Bool
forall a. Integral a => a -> a -> Bool
dividesBy a
n) [a]
ns)
isPrime'' :: Integral a => a -> Bool
isPrime'' :: forall a. Integral a => a -> Bool
isPrime'' a
n
| a
n a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
1 = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (a
n `dividesBy`) ([a] -> Bool) -> [a] -> Bool
forall a b. (a -> b) -> a -> b
$ (a -> Bool) -> [a] -> [a]
forall a. (a -> Bool) -> [a] -> [a]
takeWhile (\a
k -> a
ka -> a -> a
forall a. Num a => a -> a -> a
*a
k a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= a
n) [a]
forall a. Integral a => [a]
primes
| Bool
otherwise = Bool
False