Ramanujan primes: Difference between revisions

Replaced Phix algorithm by C++ algorithm which precomputes the values of the pi function. Added the 100_000th Ramanujan prime.
(Replaced Phix algorithm by C++ algorithm which precomputes the values of the pi function. Added the 100_000th Ramanujan prime.)
Line 326:
 
=={{header|Nim}}==
{{trans|PhixC++}}
I compiled using command <code>nim c -d:release -d:lto --gc:arc ramanujan_primes.nim</code>, i.e. with runtime checks on and, link time optimization and using Arc garbage collector. TheTo find the 100_000th Ramanujan prime, the program runs in about 35100 ms on my laptop (i5-8250U CPU @ 1.60GHz, 8 GB Ram, Linux Manjaro). Fast, but this is normal for native code.
This is a straight translation of Phix version, but I had to add some code to manage prime numbers. Note also that in Nim sequences starts at index 0, not 1.
 
<lang Nim>import algorithmmath, mathsequtils, strutils, times
I compiled using command <code>nim c -d:release -d:lto ramanujan_primes.nim</code>, i.e. with runtime checks on and link time optimization. The program runs in about 35 ms on my laptop (i5-8250U CPU @ 1.60GHz, 8 GB Ram, Linux Manjaro). Fast, but this is normal for native code.
 
<lang Nim>import algorithm, math, strutils, times
 
let t0 = now()
 
type PrimeCounter = seq[int]
const N = 400_000
 
proc initPrimeCounter(limit: Positive): PrimeCounter =
var composite: array[2..N, bool]
doAssert limit > 1
for n in 2..N:
let n2result = n *repeat(1, nlimit)
result[0] = piCache[n-1]0
if n2 > N: break
result[1] = 0
if not composite[n]:
for ki in countup(n24, Nlimit - 1, n2): result[i] = 0
var composite[k]p = true3
var p2 = 9
while p2 < limit:
if result[p] != 0:
for q in countup(p2, limit - 1, p shl 1):
if not comp: result.add[q] = i0
p2 += (p + 1) shl 2
if n2p2 >= Nlimit: break
inc p, 2
# Compute partial sums in place.
var sum = 0
for item in result.mitems:
sum += item
item = sum
 
func ramanujanMax(n: int): int {.inline.} = int(ceil(4 * n.toFloat * ln(4 * n.toFloat)))
proc primesLe(n: int): seq[int] =
for i, comp in composite:
if i > n: break
if not comp: result.add i
 
proc ramanujanPrime(pi: PrimeCounter; n: int): int =
var piCache: seq[int]
 
proc pi(n: int): int =
if n == 0: return 0
if n > piCache.len:
let primes = primesLe(n)
for i in piCache.len+1..n:
let k = primes.upperBound(i)
piCache.add k
result = piCache[n-1]
 
proc ramanujanPrime(n: int): int =
let maxPoss = int(ceil(4 * n.toFloat * ln(4 * n.toFloat)))
for i in countdown(maxPoss, 1):
if pi([i)] - pi([i div 2)] < n:
return i + 1
 
let pi = initPrimeCounter(1 + ramanujanMax(100_000))
 
for n in 1..100:
stdout.write ($ramanujanPrime(pi, n)).align(4), if n mod 20 == 0: '\n' else: ' '
 
echo "\nThe 1000th Ramanujan prime is ", ramanujanPrime(1000pi, 1_000)
echo "The 10000th10_000th Ramanujan prime is ", ramanujanPrime(10000pi, 10_000)
echo "The 100_000th Ramanujan prime is ", ramanujanPrime(pi, 100_000)
 
echo "\nElapsed time: ", (now() - t0).inMilliseconds, " ms"</lang>
Line 383:
 
The 1000th Ramanujan prime is 19403
The 10000th10_000th Ramanujan prime is 242057
The 100_000th Ramanujan prime is 2916539
 
Elapsed time: 3499 ms</pre>
 
=={{header|Perl}}==
Anonymous user