Initial data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 72d218235f
commit f23f22d71c
199087 changed files with 3378941 additions and 0 deletions

View file

@ -0,0 +1,26 @@
#!/usr/bin/env runghc
import Data.List
import Data.Numbers.Primes
import System.IO
firstNPrimes :: Integer -> [Integer]
firstNPrimes n = genericTake n primes
primesBetweenInclusive :: Integer -> Integer -> [Integer]
primesBetweenInclusive lo hi =
dropWhile (< lo) $ takeWhile (<= hi) primes
nthPrime :: Integer -> Integer
nthPrime n = genericIndex primes (n - 1) -- beware 0-based indexing
main = do
hSetBuffering stdout NoBuffering
putStr "First 20 primes: "
print $ firstNPrimes 20
putStr "Primes between 100 and 150: "
print $ primesBetweenInclusive 100 150
putStr "Number of primes between 7700 and 8000: "
print $ genericLength $ primesBetweenInclusive 7700 8000
putStr "The 10000th prime: "
print $ nthPrime 10000

View file

@ -0,0 +1,11 @@
λ> take 20 primesW
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]
λ> takeWhile (< 150) . dropWhile (< 100) $ primesW
[101,103,107,109,113,127,131,137,139,149]
λ> length . takeWhile (< 8000) . dropWhile (< 7700) $ primesW
30
λ> (!! (10000-1)) primesW
104729

View file

@ -0,0 +1,68 @@
{-# LANGUAGE PostfixOperators #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleInstances #-}
import Data.Numbers.Primes
import Data.Array.Unboxed hiding ((!))
import qualified Data.Array.Unboxed as Array
import Data.CReal
import Data.CReal.Internal
import GHC.TypeLits
instance KnownNat n => Enum (CReal n) where
toEnum i = fromIntegral i
fromEnum _ = error "Cannot fromEnum CReal"
enumFrom = iterate (+ 1)
enumFromTo n e = takeWhile (<= e) $ iterate (+ 1)n
enumFromThen n m = iterate (+(m-n)) n
enumFromThenTo n m e = if m >= n then takeWhile (<= e) $ iterate (+(m-n)) n
else takeWhile (>= e) $ iterate (+(m-n)) n
-- partial_sum x y a b = (p,q) where
-- p/q = sum_{a<i<=b} x(i) / poduct_{a<j<=j} y(j)
-- The complexity of partial_sum x y 0 n is O(n log n)
partial_sum x y = pq where
pq a b = if a>=b then (0,1)
else if a==b-1 then (fromIntegral $ x b, fromIntegral $ y b )
else (p_ab,q_ab)
where
c=(a+b) `div` 2
(p_ac,q_ac) = pq a c
(p_cb,q_cb) = pq c b
p_ab = p_cb + q_cb*p_ac
q_ab = q_ac*q_cb
-- c is the real constant that is used in the formula for primes
-- c = sum_{1<i} p_i / (2i+1)!
-- where p_i is i-th prime.
-- This will work for any sequence of integers p, where |p_n| < 2n(2n+1) * 0.375
c = crMemoize f where
f n = 2^n * p `div` q where
n' = fromIntegral n
u = head [ceiling (x) | x<-[(n' * log 2/ (log n'-1)/2 ) ..] , 2*x*log (2*x) - 2*x > n'*log 2]
-- Invariant: (2u+1)! > 2^n
ar :: UArray Int Int
ar = listArray (1,u) $ primes
(p,q) = partial_sum (ar Array.!) (\n-> 2*n*(2*n+1) ) 0 u
-- Fractorial part of x
-- By definition it is in the interval [-0.5; 0.5]
-- But it gurantes to work corectly if fractional part of x is in (-0.375; 0.375)
fract x = x - fromIntegral (round (x :: CReal 3))
-- Factorial.
-- The complexity of (n!) is O(n log n) (which is better than O(n^2) for product [1..n] )
(!) :: (RealFrac a, Num b) => a -> b
(!) = fromIntegral . snd . partial_sum (const 0) id 0 . round
-- Analytic function for n-th prime.
-- NB. Strictly speaking this function is not analytic, because it uses factorial, fractional part and round functions
-- To make it truly analytic you need to replace
-- fract x = acos (cos (2*pi*x)) / (2*pi)
-- round x = x - fract x
-- and use the Gamma function instead of factorial.
-- Then you will get analytic function prime :: CReal 0 -> CReal 0
prime n = round( 2*n*(2*n+1) * fract ( c * ((2*n-1)!)))

View file

@ -0,0 +1,13 @@
λ> :set +s
λ> prime 10000
104729
(0.32 secs, 179,899,272 bytes)
λ> length $ dropWhile (< 7700) $ takeWhile (< 8000) $ map prime [1..]
30
(3.09 secs, 3,418,225,920 bytes)
λ> dropWhile (< 100) $ takeWhile (< 150) $ map prime [1..]
[101,103,107,109,113,127,131,137,139,149]
(0.02 secs, 20,239,464 bytes)
λ> map prime [1..20]
[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]
(0.01 secs, 10,485,208 bytes)

View file

@ -0,0 +1 @@
![2,3,5,7] | (nc := 11) | (nc +:= |wheel2345)

View file

@ -0,0 +1,38 @@
import Collections # to get the Heap class for use as a Priority Queue
record filter(composite, prime) # next composite involving this prime
procedure main()
every writes((primes()\20)||" " | "\n")
every p := primes() do if 100 < p < 150 then writes(p," ") else if p >= 150 then break write()
every (n := 0, p := primes()) do if 7700 < p < 8000 then n +:= 1 else if p >= 8000 then break write(n)
every (i := 1, p := primes()) do if (i+:=1) >= 10000 then break write(p)
end
procedure primes()
local wheel2357, nc
wheel2357 := [2, 4, 2, 4, 6, 2, 6, 4, 2, 4, 6, 6, 2, 6, 4, 2,
6, 4, 6, 8, 4, 2, 4, 2, 4, 8, 6, 4, 6, 2, 4, 6,
2, 6, 6, 4, 2, 4, 6, 2, 6, 4, 2, 4, 2, 10, 2, 10]
suspend sieve(Heap(,getCompositeField), ![2,3,5.7] | (nc := 11) | (nc +:= |!wheel2357))
end
procedure sieve(pQueue, candidate)
local nc
if 0 = pQueue.size() then { # 2 is prime
pQueue.add(filter(candidate*candidate, candidate))
return candidate
}
while candidate > (nc := pQueue.get()).composite do {
nc.composite +:= nc.prime
pQueue.add(nc)
}
pQueue.add(filter(nc.composite+nc.prime, nc.prime))
if candidate < nc.composite then { # new prime found!
pQueue.add(filter(candidate*candidate, candidate))
return candidate
}
end
# Provide a function for comparing filters in the priority queue...
procedure getCompositeField(x); return x.composite; end