module Data.Numbers.Primes (
primes, wheelSieve,
isPrime, primeFactors
) where
primes :: Integral int => [int]
primes :: forall int. Integral int => [int]
primes = forall int. Integral int => Int -> [int]
wheelSieve Int
6
{-# SPECIALISE primes :: [Int] #-}
{-# SPECIALISE primes :: [Integer] #-}
wheelSieve :: Integral int
=> Int
-> [int]
wheelSieve :: forall int. Integral int => Int -> [int]
wheelSieve Int
k = forall a. [a] -> [a]
reverse [int]
ps forall a. [a] -> [a] -> [a]
++ forall a b. (a -> b) -> [a] -> [b]
map forall a. [a] -> a
head (forall int. (Ord int, Num int) => int -> [int] -> [[int]]
sieve int
p (forall a. [a] -> [a]
cycle [int]
ns))
where (int
p:[int]
ps,[int]
ns) = forall int. Integral int => Int -> Wheel int
wheel Int
k
{-# SPECIALISE wheelSieve :: Int -> [Int] #-}
{-# SPECIALISE wheelSieve :: Int -> [Integer] #-}
isPrime :: Integral int => int -> Bool
isPrime :: forall int. Integral int => int -> Bool
isPrime int
n | int
n forall a. Ord a => a -> a -> Bool
> int
1 = forall int. Integral int => int -> [int]
primeFactors int
n forall a. Eq a => a -> a -> Bool
== [int
n]
| Bool
otherwise = Bool
False
{-# SPECIALISE isPrime :: Int -> Bool #-}
{-# SPECIALISE isPrime :: Integer -> Bool #-}
primeFactors :: Integral int => int -> [int]
primeFactors :: forall int. Integral int => int -> [int]
primeFactors int
n = forall {a}. Integral a => a -> [a] -> [a]
factors int
n (forall int. Integral int => Int -> [int]
wheelSieve Int
6)
where
factors :: a -> [a] -> [a]
factors a
1 [a]
_ = []
factors a
m (a
p:[a]
ps) | a
m forall a. Ord a => a -> a -> Bool
< a
pforall a. Num a => a -> a -> a
*a
p = [a
m]
| a
r forall a. Eq a => a -> a -> Bool
== a
0 = a
p forall a. a -> [a] -> [a]
: a -> [a] -> [a]
factors a
q (a
pforall a. a -> [a] -> [a]
:[a]
ps)
| Bool
otherwise = a -> [a] -> [a]
factors a
m [a]
ps
where (a
q,a
r) = forall a. Integral a => a -> a -> (a, a)
quotRem a
m a
p
{-# SPECIALISE primeFactors :: Int -> [Int] #-}
{-# SPECIALISE primeFactors :: Integer -> [Integer] #-}
sieve :: (Ord int, Num int) => int -> [int] -> [[int]]
sieve :: forall int. (Ord int, Num int) => int -> [int] -> [[int]]
sieve int
p ns :: [int]
ns@(int
m:[int]
ms) = forall int. Num int => int -> [int] -> [int]
spin int
p [int]
ns forall a. a -> [a] -> [a]
: forall int.
(Ord int, Num int) =>
int -> [int] -> Composites int -> [[int]]
sieveComps (int
pforall a. Num a => a -> a -> a
+int
m) [int]
ms (forall int. (Ord int, Num int) => int -> [int] -> Composites int
composites int
p [int]
ns)
{-# SPECIALISE sieve :: Int -> [Int] -> [[Int]] #-}
{-# SPECIALISE sieve :: Integer -> [Integer] -> [[Integer]] #-}
type Composites int = (Queue int,[[int]])
composites :: (Ord int, Num int) => int -> [int] -> Composites int
composites :: forall int. (Ord int, Num int) => int -> [int] -> Composites int
composites int
p [int]
ns = (forall int. Queue int
Empty, forall a b. (a -> b) -> [a] -> [b]
map forall {b}. Num b => [b] -> [b]
comps (forall int. Num int => int -> [int] -> [int]
spin int
p [int]
ns forall a. a -> [a] -> [a]
: forall int. (Ord int, Num int) => int -> [int] -> [[int]]
sieve int
p [int]
ns))
where comps :: [b] -> [b]
comps xs :: [b]
xs@(b
x:[b]
_) = forall a b. (a -> b) -> [a] -> [b]
map (b
xforall a. Num a => a -> a -> a
*) [b]
xs
{-# SPECIALISE composites :: Int -> [Int] -> Composites Int #-}
{-# SPECIALISE composites :: Integer -> [Integer] -> Composites Integer #-}
splitComposites :: Ord int => Composites int -> (int,Composites int)
splitComposites :: forall int. Ord int => Composites int -> (int, Composites int)
splitComposites (Queue int
Empty, [int]
xs:[[int]]
xss) = forall int. Ord int => Composites int -> (int, Composites int)
splitComposites (forall int. [int] -> [Queue int] -> Queue int
Fork [int]
xs [], [[int]]
xss)
splitComposites (Queue int
queue, xss :: [[int]]
xss@((int
x:[int]
xs):[[int]]
yss))
| int
x forall a. Ord a => a -> a -> Bool
< int
z = (int
x, forall int. Ord int => int -> Composites int -> Composites int
discard int
x (forall int. Ord int => [int] -> Queue int -> Queue int
enqueue [int]
xs Queue int
queue, [[int]]
yss))
| Bool
otherwise = (int
z, forall int. Ord int => int -> Composites int -> Composites int
discard int
z (forall int. Ord int => [int] -> Queue int -> Queue int
enqueue [int]
zs Queue int
queue', [[int]]
xss))
where (int
z:[int]
zs,Queue int
queue') = forall int. Ord int => Queue int -> ([int], Queue int)
dequeue Queue int
queue
{-# SPECIALISE splitComposites :: Composites Int -> (Int,Composites Int) #-}
{-# SPECIALISE
splitComposites :: Composites Integer -> (Integer,Composites Integer) #-}
discard :: Ord int => int -> Composites int -> Composites int
discard :: forall int. Ord int => int -> Composites int -> Composites int
discard int
n Composites int
ns | int
n forall a. Eq a => a -> a -> Bool
== int
m = forall int. Ord int => int -> Composites int -> Composites int
discard int
n Composites int
ms
| Bool
otherwise = Composites int
ns
where (int
m,Composites int
ms) = forall int. Ord int => Composites int -> (int, Composites int)
splitComposites Composites int
ns
{-# SPECIALISE discard :: Int -> Composites Int -> Composites Int #-}
{-# SPECIALISE
discard :: Integer -> Composites Integer -> Composites Integer #-}
sieveComps :: (Ord int, Num int) => int -> [int] -> Composites int -> [[int]]
sieveComps :: forall int.
(Ord int, Num int) =>
int -> [int] -> Composites int -> [[int]]
sieveComps int
cand ns :: [int]
ns@(int
m:[int]
ms) Composites int
xs
| int
cand forall a. Eq a => a -> a -> Bool
== int
comp = forall int.
(Ord int, Num int) =>
int -> [int] -> Composites int -> [[int]]
sieveComps (int
candforall a. Num a => a -> a -> a
+int
m) [int]
ms Composites int
ys
| int
cand forall a. Ord a => a -> a -> Bool
< int
comp = forall int. Num int => int -> [int] -> [int]
spin int
cand [int]
ns forall a. a -> [a] -> [a]
: forall int.
(Ord int, Num int) =>
int -> [int] -> Composites int -> [[int]]
sieveComps (int
candforall a. Num a => a -> a -> a
+int
m) [int]
ms Composites int
xs
| Bool
otherwise = forall int.
(Ord int, Num int) =>
int -> [int] -> Composites int -> [[int]]
sieveComps int
cand [int]
ns Composites int
ys
where (int
comp,Composites int
ys) = forall int. Ord int => Composites int -> (int, Composites int)
splitComposites Composites int
xs
{-# SPECIALISE sieveComps :: Int -> [Int] -> Composites Int -> [[Int]] #-}
{-# SPECIALISE
sieveComps :: Integer -> [Integer] -> Composites Integer -> [[Integer]] #-}
spin :: Num int => int -> [int] -> [int]
spin :: forall int. Num int => int -> [int] -> [int]
spin int
x (int
y:[int]
ys) = int
x forall a. a -> [a] -> [a]
: forall int. Num int => int -> [int] -> [int]
spin (int
xforall a. Num a => a -> a -> a
+int
y) [int]
ys
{-# SPECIALISE spin :: Int -> [Int] -> [Int] #-}
{-# SPECIALISE spin :: Integer -> [Integer] -> [Integer] #-}
type Wheel int = ([int],[int])
wheel :: Integral int => Int -> Wheel int
wheel :: forall int. Integral int => Int -> Wheel int
wheel Int
n = forall a. (a -> a) -> a -> [a]
iterate forall int. Integral int => Wheel int -> Wheel int
next ([int
2],[int
1]) forall a. [a] -> Int -> a
!! Int
n
{-# SPECIALISE wheel :: Int -> Wheel Int #-}
{-# SPECIALISE wheel :: Int -> Wheel Integer #-}
next :: Integral int => Wheel int -> Wheel int
next :: forall int. Integral int => Wheel int -> Wheel int
next (ps :: [int]
ps@(int
p:[int]
_),[int]
xs) = (int
pyforall a. a -> [a] -> [a]
:[int]
ps,forall int. Integral int => int -> int -> int -> [int] -> [int]
cancel (forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
product [int]
ps) int
p int
py [int]
ys)
where (int
y:[int]
ys) = forall a. [a] -> [a]
cycle [int]
xs
py :: int
py = int
p forall a. Num a => a -> a -> a
+ int
y
{-# SPECIALISE next :: Wheel Int -> Wheel Int #-}
{-# SPECIALISE next :: Wheel Integer -> Wheel Integer #-}
cancel :: Integral int => int -> int -> int -> [int] -> [int]
cancel :: forall int. Integral int => int -> int -> int -> [int] -> [int]
cancel int
0 int
_ int
_ [int]
_ = []
cancel int
m int
p int
n (int
x:ys :: [int]
ys@(int
y:[int]
zs))
| int
nx forall a. Integral a => a -> a -> a
`mod` int
p forall a. Ord a => a -> a -> Bool
> int
0 = int
x forall a. a -> [a] -> [a]
: forall int. Integral int => int -> int -> int -> [int] -> [int]
cancel (int
mforall a. Num a => a -> a -> a
-int
x) int
p int
nx [int]
ys
| Bool
otherwise = forall int. Integral int => int -> int -> int -> [int] -> [int]
cancel int
m int
p int
n (int
xforall a. Num a => a -> a -> a
+int
yforall a. a -> [a] -> [a]
:[int]
zs)
where nx :: int
nx = int
n forall a. Num a => a -> a -> a
+ int
x
{-# SPECIALISE cancel :: Int -> Int -> Int -> [Int] -> [Int] #-}
{-# SPECIALISE
cancel :: Integer -> Integer -> Integer -> [Integer] -> [Integer] #-}
data Queue int = Empty | Fork [int] [Queue int]
enqueue :: Ord int => [int] -> Queue int -> Queue int
enqueue :: forall int. Ord int => [int] -> Queue int -> Queue int
enqueue [int]
ns = forall int. Ord int => Queue int -> Queue int -> Queue int
merge (forall int. [int] -> [Queue int] -> Queue int
Fork [int]
ns [])
{-# SPECIALISE enqueue :: [Int] -> Queue Int -> Queue Int #-}
{-# SPECIALISE enqueue :: [Integer] -> Queue Integer -> Queue Integer #-}
merge :: Ord int => Queue int -> Queue int -> Queue int
merge :: forall int. Ord int => Queue int -> Queue int -> Queue int
merge Queue int
Empty Queue int
y = Queue int
y
merge Queue int
x Queue int
Empty = Queue int
x
merge Queue int
x Queue int
y | forall {int}. Queue int -> int
prio Queue int
x forall a. Ord a => a -> a -> Bool
<= forall {int}. Queue int -> int
prio Queue int
y = forall {int}. Queue int -> Queue int -> Queue int
join Queue int
x Queue int
y
| Bool
otherwise = forall {int}. Queue int -> Queue int -> Queue int
join Queue int
y Queue int
x
where prio :: Queue int -> int
prio (Fork (int
n:[int]
_) [Queue int]
_) = int
n
join :: Queue int -> Queue int -> Queue int
join (Fork [int]
ns [Queue int]
qs) Queue int
q = forall int. [int] -> [Queue int] -> Queue int
Fork [int]
ns (Queue int
qforall a. a -> [a] -> [a]
:[Queue int]
qs)
{-# SPECIALISE merge :: Queue Int -> Queue Int -> Queue Int #-}
{-# SPECIALISE merge :: Queue Integer -> Queue Integer -> Queue Integer #-}
dequeue :: Ord int => Queue int -> ([int], Queue int)
dequeue :: forall int. Ord int => Queue int -> ([int], Queue int)
dequeue (Fork [int]
ns [Queue int]
qs) = ([int]
ns,forall int. Ord int => [Queue int] -> Queue int
mergeAll [Queue int]
qs)
{-# SPECIALISE dequeue :: Queue Int -> ([Int], Queue Int) #-}
{-# SPECIALISE dequeue :: Queue Integer -> ([Integer], Queue Integer) #-}
mergeAll :: Ord int => [Queue int] -> Queue int
mergeAll :: forall int. Ord int => [Queue int] -> Queue int
mergeAll [] = forall int. Queue int
Empty
mergeAll [Queue int
x] = Queue int
x
mergeAll (Queue int
x:Queue int
y:[Queue int]
qs) = forall int. Ord int => Queue int -> Queue int -> Queue int
merge (forall int. Ord int => Queue int -> Queue int -> Queue int
merge Queue int
x Queue int
y) (forall int. Ord int => [Queue int] -> Queue int
mergeAll [Queue int]
qs)
{-# SPECIALISE mergeAll :: [Queue Int] -> Queue Int #-}
{-# SPECIALISE mergeAll :: [Queue Integer] -> Queue Integer #-}