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