Task: Ramanujan primes


C++: #include <chrono>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <numeric>
#include <vector>

class prime_counter {
public:
    explicit prime_counter(int limit);
    int prime_count(int n) const { return n < 1 ? 0 : count_.at(n); }

private:
    std::vector<int> count_;
};

prime_counter::prime_counter(int limit) : count_(limit, 1) {
    if (limit > 0)
        count_[0] = 0;
    if (limit > 1)
        count_[1] = 0;
    for (int i = 4; i < limit; i += 2)
        count_[i] = 0;
    for (int p = 3, sq = 9; sq < limit; p += 2) {
        if (count_[p]) {
            for (int q = sq; q < limit; q += p << 1)
                count_[q] = 0;
        }
        sq += (p + 1) << 2;
    }
    std::partial_sum(count_.begin(), count_.end(), count_.begin());
}

int ramanujan_max(int n) {
    return static_cast<int>(std::ceil(4 * n * std::log(4 * n)));
}

int ramanujan_prime(const prime_counter& pc, int n) {
    int max = ramanujan_max(n);
    for (int i = max; i >= 0; --i) {
        if (pc.prime_count(i) - pc.prime_count(i / 2) < n)
            return i + 1;
    }
    return 0;
}

int main() {
    std::cout.imbue(std::locale(""));
    auto start = std::chrono::high_resolution_clock::now();
    prime_counter pc(1 + ramanujan_max(100000));
    for (int i = 1; i <= 100; ++i) {
        std::cout << std::setw(5) << ramanujan_prime(pc, i)
                  << (i % 10 == 0 ? '\n' : ' ');
    }
    std::cout << '\n';
    for (int n = 1000; n <= 100000; n *= 10) {
        std::cout << "The " << n << "th Ramanujan prime is " << ramanujan_prime(pc, n)
              << ".\n";
    }
    auto end = std::chrono::high_resolution_clock::now();
    std::cout << "\nElapsed time: "
              << std::chrono::duration<double>(end - start).count() * 1000
              << " milliseconds\n";
}



Go: package main

import (
    "fmt"
    "math"
    "rcu"
    "time"
)

var count []int

func primeCounter(limit int) {
    count = make([]int, limit)
    for i := 0; i < limit; i++ {
        count[i] = 1
    }
    if limit > 0 {
        count[0] = 0
    }
    if limit > 1 {
        count[1] = 0
    }
    for i := 4; i < limit; i += 2 {
        count[i] = 0
    }
    for p, sq := 3, 9; sq < limit; p += 2 {
        if count[p] != 0 {
            for q := sq; q < limit; q += p << 1 {
                count[q] = 0
            }
        }
        sq += (p + 1) << 2
    }
    sum := 0
    for i := 0; i < limit; i++ {
        sum += count[i]
        count[i] = sum
    }
}

func primeCount(n int) int {
    if n < 1 {
        return 0
    }
    return count[n]
}

func ramanujanMax(n int) int {
    fn := float64(n)
    return int(math.Ceil(4 * fn * math.Log(4*fn)))
}

func ramanujanPrime(n int) int {
    if n == 1 {
        return 2
    }
    for i := ramanujanMax(n); i >= 2*n; i-- {
        if i%2 == 1 {
            continue
        }
        if primeCount(i)-primeCount(i/2) < n {
            return i + 1
        }
    }
    return 0
}

func main() {
    start := time.Now()
    primeCounter(1 + ramanujanMax(1e6))
    fmt.Println("The first 100 Ramanujan primes are:")
    rams := make([]int, 100)
    for n := 0; n < 100; n++ {
        rams[n] = ramanujanPrime(n + 1)
    }
    for i, r := range rams {
        fmt.Printf("%5s ", rcu.Commatize(r))
        if (i+1)%10 == 0 {
            fmt.Println()
        }
    }

    fmt.Printf("\nThe 1,000th Ramanujan prime is %6s\n", rcu.Commatize(ramanujanPrime(1000)))

    fmt.Printf("\nThe 10,000th Ramanujan prime is %7s\n", rcu.Commatize(ramanujanPrime(10000)))

    fmt.Printf("\nThe 100,000th Ramanujan prime is %6s\n", rcu.Commatize(ramanujanPrime(100000)))

    fmt.Printf("\nThe 1,000,000th Ramanujan prime is %7s\n", rcu.Commatize(ramanujanPrime(1000000)))

    fmt.Println("\nTook", time.Since(start))
}