title: Arbitrary Randomness (Speed edition)

text:
# Question
Title: Arbitrary Randomness (Speed edition)
Given integer `n`, calculate a set of `n` random unique integers in range `1..n^2` (inclusive) such that the sum of the set is equal to `n^2`

Random, in this case, means *uniformly* random between valid outputs. Each valid output for a given `n` must have a uniform chance of being generated.

For example, `n=3` should have a 1/3 chance each of outputting `6, 1, 2`, `3, 5, 1`, or `4, 3, 2`. As this is a set, order is irrelevant, `4, 3, 2` is identical to `3, 2, 4`

## Scoring

The winner is the program that can compute the highest `n` in under 60 seconds.
*Note:* To prevent possible partial hardcoding, all entries must be under 4000 bytes

## Testing

All code will be run on my local Windows 10 machine (Razer Blade 15, 16GB RAM, Intel i7-8750H 6 cores, 4.1GHz, GTX 1060 in case you want to abuse the GPU) so please provide detailed instructions to run your code on my machine.
At request, entries can be run either via Debian on WSL, or on a Xubuntu Virtual Machine (both on the same machine as above)

Submissions will be run 50 times in succession, final score will be an average of all 50 results.

# Answer
> 6 votes
# Rust, *n* ≈ 1400

### How to run

Build with `cargo build --release`, and run with `target/release/arbitrary-randomness n`.

This program runs fastest with lots of memory (as long as it’s not swapping, of course). You can adjust its memory usage by editing the `MAX_BYTES` constant, currently set at 8 GiB.

### How it works

The set is constructed by a sequence of binary decisions (each number is either inside or outside the set), each of whose probabilities are computed combinatorially by counting the number of possible sets constructible after each choice using dynamic programming.

Memory usage for large *n* is reduced by using a version of this binomial partitioning strategy.

### `Cargo.toml`

```
[package]
name = "arbitrary-randomness"
version = "0.1.0"
authors = ["Anders Kaseorg <andersk@mit.edu>"]

[dependencies]
rand = "0.6"

```

### `src/main.rs`

```
extern crate rand;

use rand::prelude::*;
use std::env;
use std::f64;
use std::mem;

const MAX_BYTES: usize = 8 << 30; // 8 gibibytes

fn ln_add_exp(a: f64, b: f64) -> f64 {
    if a > b {
        (b - a).exp().ln_1p() + a
    } else {
        (a - b).exp().ln_1p() + b
    }
}

fn split(steps: usize, memory: usize) -> usize {
    if steps == 1 {
        return 0;
    }
    let mut u0 = 0;
    let mut n0 = f64::INFINITY;
    let mut u1 = steps;
    let mut n1 = -f64::INFINITY;
    while u1 - u0 > 1 {
        let u = (u0 + u1) / 2;
        let k = (memory * steps) as f64 / u as f64;
        let n = (0..memory)
            .map(|i| (k - i as f64) / (i as f64 + 1.))
            .product();
        if n > steps as f64 {
            u0 = u;
            n0 = n;
        } else {
            u1 = u;
            n1 = n;
        }
    }
    if n0 - (steps as f64) <= steps as f64 - n1 {
        u0
    } else {
        u1
    }
}

fn gen(n: usize, rng: &mut impl Rng) -> Vec<usize> {
    let s = n * n.wrapping_sub(1) / 2;
    let width = n.min(MAX_BYTES / ((s + 1) * mem::size_of::<f64>()));
    let ix = |m: usize, k: usize| m + k * (s + 1);
    let mut ln_count = vec![-f64::INFINITY; ix(0, width)];
    let mut checkpoints = Vec::with_capacity(width);
    let mut a = Vec::with_capacity(n);
    let mut m = s;
    let mut x = 1;

    for k in (1..=n).rev() {
        let i = loop {
            let i = checkpoints.len();
            let k0 = *checkpoints.last().unwrap_or(&0);
            if k0 == k {
                checkpoints.pop();
                break i - 1;
            }
            if i == 0 {
                ln_count[ix(0, i)] = 0.;
                for m in 1..=s {
                    ln_count[ix(m, i)] = -f64::INFINITY;
                }
            } else {
                for m in 0..=s {
                    ln_count[ix(m, i)] = ln_count[ix(m, i - 1)];
                }
            }
            let k1 = k - split(k - k0, width - 1 - i);
            for step in k0 + 1..=k1 {
                for m in step..=s {
                    ln_count[ix(m, i)] = ln_add_exp(ln_count[ix(m - step, i)], ln_count[ix(m, i)]);
                }
            }
            if k1 == k {
                break i;
            }
            checkpoints.push(k1);
        };

        while m >= k && rng.gen_bool((ln_count[ix(m - k, i)] - ln_count[ix(m, i)]).exp()) {
            m -= k;
            x += 1;
        }
        a.push(x);
        x += 1;
    }
    a
}

fn main() {
    if let [_, n] = &env::args().collect::<Vec<_>>()[..] {
        let n = n.parse().unwrap();
        let mut rng = StdRng::from_entropy();
        println!("{:?}", gen(n, &mut rng));
    } else {
        panic!("expected one argument");
    }
}

```

Try it online!

(Note: the TIO version has a few modifications. First, the memory limit is reduced to 1 GiB. Second, since TIO doesn’t let you write a `Cargo.toml` and depend on external crates like `rand`, I instead pulled in `drand48` from the C library using the FFI. I didn’t bother to seed it, so the TIO version will produce the same result on every run. Don’t use the TIO version for official benchmarking.)

# Answer
> 3 votes
# Java 7+, n=50 in ~30 sec on TIO

```
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.Random;
class Main{
  public static void main(String[] a){

    int n=50;

    Random randomGenerator = new Random();
    int i = n+1;
    int squaredN = n*n;
    int[]randomIntegers = new int[i];
    randomIntegers[n] = squaredN;
    while(true){
      for(i=n; i-->1; ){
        randomIntegers[i] = randomGenerator.nextInt(squaredN);
      }
      Set<Integer> result = new HashSet<>();
      Arrays.sort(randomIntegers);
      for(i=n; i-->0; ){
        result.add(randomIntegers[i+1] - randomIntegers[i]);
      }
      if(!result.contains(0) && result.size()==n){
        System.out.println(result);
        return;
      }
    }
  }
}

```

Ungolfed version of my answer for the code-golf version of this challenge for now, with only one minor change: `java.util.Random#nextInt(limit)` is used instead of `(int)(Math.random()*limit)` for an integer in the range `[0, n)`, since it's about twice as fast.

Try it online.

## Explanation:

**Approach used:**

The code is split into two parts:

1. Generate a list of `n` amount of random integers that sum to `n squared`.
2. Then it checks if all values are unique and none are zero, and if either is falsey, it will try step 1 again, rinsing and repeating until we have a result.

Step 1 is done with the following sub-steps:

1) Generate an array of `n-1` amount of random integers in the range `[0, n squared)`. And add `0` and `n squared` to this list. This is done in `O(n+1)` performance.
2) Then it will sort the array with the builtin `java.util.Arrays.sort(int[])`, This is done in `O(n*log(n))` performance, as is stated in the docs:

> Sorts the specified array of ints into ascending numerical order. The sorting algorithm is a tuned quicksort, adapted from Jon L. Bentley and M. Douglas McIlroy's "Engineering a Sort Function", Software-Practice and Experience, Vol. 23(11) P. 1249-1265 (November 1993). This algorithm offers n\*log(n) performance on many data sets that cause other quicksorts to degrade to quadratic performance.

3) Calculate the difference between each pair. This resulting list of differences will contain `n` integers that sum to `n squared`. This is done in `O(n)` performance.

Here an example:

```
// n = 4, nSquared = 16

// n-1 amount of random integers in the range [0, nSquared):
[11, 2, 5]

// Add 0 and nSquared to it, and sort:
[0, 2, 5, 11, 16]

// Calculate differences:
[2, 3, 6, 5]

// The sum of these differences will always be equal to nSquared
sum([2, 3, 6, 5]) = 16

```

So these three steps above are pretty good for performance, unlike step 2 and the loop around the whole thing, which is a basic brute-force. Step 2 is split in these sub-steps:

1) The differences list is already saved in a `java.util.Set`. It will check if the size of this Set is equal to `n`. If it is, it means all random values we generated are unique.
2) And it will also check that it contains no `0` in the Set, since the challenge asks for random values in the range `[1, X]`, where `X` is `n squared` minus the sum of `[1, ..., n-1]`, as stated by *@Skidsdev* in the comment below.

If either of the two options above (not all values are unique, or a zero is present), it will generate a new array and Set again by resetting to step 1. This continues until we have a result. Because of this, the time can vary quite a bit. I've seen it finish in 3 seconds once on TIO for `n=50`, but also in 55 seconds once for `n=50`.

**Prove of uniformity:**

I'm not entirely sure how to prove this to be completely honest. The `java.util.Random#nextInt` is uniform for sure, as is described in the docs:

> Returns the next pseudorandom, uniformly distributed `int` value from this random number generator's sequence. The general contract of `nextInt` is that one `int` value is pseudorandomly generated and returned. All 232 possible `int` values are produced with (approximately) equal probability.

The differences between these (sorted) random values themselves are of course not uniform, but the sets as a whole are uniform. Again, I'm not sure how to prove this mathematically, but here is a script that will put `10,000` generated sets (for `n=10`) in a Map with a counter, where most sets are unique; some repeated twice; and the maximum repeated occurrence is usually in the range `[4,8]`.

**Installation instructions:**

Since Java is a pretty well-known language with plenty of information available on how to create and run Java code, I will keep this short.
All the tools used in my code are available in Java 7 (perhaps even already in Java 5 or 6, but let's use 7 just in case). I'm pretty sure Java 7 is already archived though, so I would suggest downloading Java 8 to run my code.

**Thoughts regarding improvements:**

I'd like to find an improvement for the check for zeros and check all values are unique. I could check for `0` before, by making sure the random value we add to the array isn't already in it, but it would mean a couple of things: the array should be an `ArrayList` so we can use the builtin method `.contains`; a while-loop should be added until we've found a random value that isn't in the List yet. Since checking for zero is now done with `.contains(0)` on the Set (which is only checked once), it's most likely better for performance to check it at that point, in comparison to adding the loop with `.contains` on the List, which will be checked at least `n` times, but most likely more.

As for the uniqueness check, we only have our `n` amount of random integers that sum to `n squared` after step 1 of the program, so only then we can check whether all are unique or not. It might be possible to keep a sortable List instead of array, and check the differences in between, but I seriously doubt it will improve the performance than just putting them in a `Set` and check if the size of that Set is `n` once.

# Answer
> 1 votes
## Mathematica n=11

```
(While[Tr@(a=RandomSample[Range[#^2-#(#-1)/2],#])!=#^2];a)&

```

# Answer
> 1 votes
# Scala, n=50 in ~45 sec on TIO

Port of @Kevin Cruijssen's Java answer in Scala.

Try it online!

```
import scala.util.Random
import scala.collection.mutable.HashSet

object Main {
  def main(args: Array[String]): Unit = {

    val n = 50
    val randomGenerator = new Random()
    val squaredN = n * n
    var randomIntegers = new Array[Int](n + 1)
    randomIntegers(n) = squaredN

    while(true) {
      for(i <- n-1 to 0 by -1) {
        randomIntegers(i) = randomGenerator.nextInt(squaredN)
      }
      val result = HashSet[Int]()
      scala.util.Sorting.quickSort(randomIntegers)
      for(i <- n-1 to 0 by -1) {
        result.add(randomIntegers(i+1) - randomIntegers(i))
      }
      if(!result.contains(0) && result.size == n) {
        println(result)
        return
      }
    }
  }
}

```

# Answer
> 1 votes
# Python, *n* ≈ 4500

Runs in expected \\$Θ(n^{5/2})\\$ time.

```
import numpy as np

def gen(n):
    target = n**2
    k_bounds = [1 / ((n + 1) / 2 - target / n), 1 / ((n + 1) / 4 - target / n)]
    i = np.arange(n)
    while (k := (k_bounds[0] + k_bounds[1]) / 2) not in k_bounds:
        p = -np.expm1(k * (n - i))
        k_bounds[int(((n - i) / p).sum() > target)] = k

    rng = np.random.default_rng()
    while True:
        output = rng.geometric(p=p).cumsum()
        if output.sum() == target:
            return output

```

Attempt This Online!

### How it works

After selecting a constant \\$k \< 0\\$ (explained below), we draw \\$n\\$ positive integers \\$a\_0, a\_1, …, a\_{n-1}\\$ independently from the geometric distributions of probabilities \\$p\_i = 1 - e^{k(n - i)}\\$. We build a candidate set from the prefix sums of the \\$a\_i\\$:

$$S = \\{a\_0, a\_0 + a\_1, …, a\_0 + a\_1 + … + a\_{n-1}\\}.$$

The probability of generating any particular \\$S\\$ can be computed as

$$\prod\_i (1 - p\_i)^{a\_i} p\_i = \prod\_i e^{k(n - i)a\_i} p\_i = e^{k \sum\_i (n - i)a\_i} \prod\_i p\_i = e^{k \sum S} \prod\_i p\_i,$$

which is proportional to \\$e^{k \sum S}\\$. In particular, the probability of generating each \\$S\\$ that sums to \\$n^2\\$ is the same! We accept \\$S\\$ if it sums to \\$n^2\\$, otherwise reject it and repeat the draw.

Although the constant \\$k\\$ has no effect on correctness, it has a huge effect on the expected running time. We select \\$k\\$ using a binary search such that \\$E\[\sum S\] = \sum\_i \frac{n - i}{p\_i}\\$ is made equal to \\$n^2\\$, in order to optimize the probability of acceptance to \\$Θ(n^{-3/2})\\$.

---
Tags: random, combinatorics, fastest-code
---


title: Calculate the number of primes up to n

text:
# Question
Title: Calculate the number of primes up to n
π(*n*) is the number of primes less than or equal to *n*.

**Input:** a natural number, *n*.

**Output:** π(n).

**Scoring:** This is a challenge. Score will be the sum of times for the score cases. I will time each entry on my computer.

**Rules and Details**

* Your code should work for *n* up to 2 billion ( 2,000,000,000 ).
* Built-ins that trivialize this are not allowed. This includes built in π functions or lists of values for π(*n*).
* Built-ins that test primality or generate primes are not allowed. This includes lists of primes, which may not be looked up externally or hardcoded locally, except with regards to the next bullet point.
* You may hardcode primes up to and including 19 and no higher.
* your implementation of π should be deterministic. This means that given a specific *n*, your code should run in (approximately) the same amount of time.
* Languages used must be freely available on Linux (Centos 7). Instructions should be included on how to run your code. Include compiler/interpreter details if necessary.
* Official times will be from my computer.
* When posting, please include a self-measured time on some/all of the test/score cases, just to give me an estimate of how fast your code is running.
* Submissions must fit in an answer post to this question.
* I am running 64bit centos7. I only have 8GB of RAM and 1GB swap. The cpu model is: AMD FX(tm)-6300 Six-Core Processor.

**Test cases(source):**

```
Input        Output
90           24
3000         430
9000         1117
4000000      283146           <--- input = 4*10^6
800000000    41146179         <--- input = 9*10^8
1100000000   55662470         <--- input = 1.1*10^9

```

**Score Cases (same source)**

As usual, these cases are subject to change. Optimizing for the scoring cases is not permitted. I may also change the number of cases in an effort to balance reasonable run times and accurate results.

```
Input        Output
1907000000   93875448         <--- input = 1.907*10^9
1337000000   66990613         <--- input = 1.337*10^9
1240000000   62366021         <--- input = 1.24*10^9
660000000    34286170         <--- input = 6.6*10^8
99820000     5751639          <--- input = 9.982*10^7
40550000     2465109          <--- input = 4.055*10^7
24850000     1557132          <--- input = 2.485*10^7
41500        4339

```

**Duration**

Since this is a challenge and entries are to be run on my computer, I reserve the right to stop timing entries after 2 weeks. After this point, entries are still accepted, but there is no guarantee that they are officially timed.

*Having said this,* I don't expect too many answers to this challenge and I will likely continue to time new answers indefinitely.

**Scoring Particulars**

I timed the faster entries with the following script:

```
#!/bin/bash

a=(1907000000 1337000000 1240000000 660000000 99820000 40550000 24850000 41500)

echo DennisC
exec 2>> times/dennisc.txt
time for j in ${a[@]}; do ./dennisc $j; done >> /dev/null;

echo DennisPy
exec 2>> times/dennispy.txt
time for j in ${a[@]}; do pypy dennispy.py <<< $j; done >> /dev/null;

echo arjandelumens
exec 2>> times/arjandelumens.txt
time for j in ${a[@]}; do ./arjandelumens $j; done >> /dev/null;

echo orlp
exec 2>> times/orlp.txt
time for j in ${a[@]}; do ./orlp $j; done >> /dev/null;

# echo mwr247
# time node-v4.3.1-linux-x64/bin/node mwr247.js

# mwr247 using js seems a bit longer, so I am going to run the fastest
# and then come back to his.

# mwr247 provided a function, so I appended
# console.log( F( <argument> ) )
# to his code, for each argument.

```

`time` writes to `stderr`, so I sent `stderr` to a log file using `exec 2 >> <filename>`. You may notice that `stdout` is sent to `/dev/null`. This isn't a problem, because I already verified that the programs were producing the correct output.

I ran the above `timeall.sh` script 10 times using `for i in {1..10}; do ./timeall.sh; done;`

I then averaged the `real time` score for each entry.

Note that no other programs were running on my computer while timing.

Also, the official times have been appended to each entry. Please double check your own average.

# Answer
> 139 votes
# C, 0.026119s (Mar 12 2016)

```
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#define cache_size 16384
#define Phi_prec_max (47 * a)

#define bit(k) (1ULL << ((k) & 63))
#define word(k) sieve[(k) >> 6]
#define sbit(k) ((word(k >> 1) >> (k >> 1)) & 1)
#define ones(k) (~0ULL >> (64 - (k)))
#define m2(k) ((k + 1) / 2)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define ns(t) (1000000000 * t.tv_sec + t.tv_nsec)
#define popcnt __builtin_popcountll

#define mask_build(i, p, o, m) mask |= m << i, i += o, i -= p * (i >= p)
#define Phi_prec_bytes ((m2(Phi_prec_max) + 1) * sizeof(int16_t))
#define Phi_prec(i, j) Phi_prec_pointer[(j) * (m2(Phi_prec_max) + 1) + (i)]
#define Phi_6_next ((i / 1155) * 480 + Phi_5[i % 1155] - Phi_5[(i + 6) / 13])
#define Phi_6_upd_1() t = Phi_6_next, i += 1, *(l++) = t
#define Phi_6_upd_2() t = Phi_6_next, i += 2, *(l++) = t, *(l++) = t
#define Phi_6_upd_3() t = Phi_6_next, i += 3, *(l++) = t, *(l++) = t, *(l++) = t

typedef unsigned __int128 uint128_t;
struct timespec then, now;
uint64_t a, primes[4648] = { 2, 3, 5, 7, 11, 13, 17, 19 }, *primes_fastdiv;
uint16_t *Phi_6, *Phi_prec_pointer;

static inline uint64_t Phi_6_mod(uint64_t y)
{
    if (y < 30030)
        return Phi_6[m2(y)];
    else
        return (y / 30030) * 5760 + Phi_6[m2(y % 30030)];
}

static inline uint64_t fastdiv(uint64_t dividend, uint64_t fast_divisor)
{
    return ((uint128_t) dividend * fast_divisor) >> 64;
}

uint64_t Phi(uint64_t y, uint64_t c)
{
    uint64_t *d = primes_fastdiv, i = 0, r = Phi_6_mod(y), t = y / 17;

    r -= Phi_6_mod(t), t = y / 19;

    while (i < c && t > Phi_prec_max) r -= Phi(t, i++), t = fastdiv(y, *(d++));

    while (i < c && t) r -= Phi_prec(m2(t), i++), t = fastdiv(y, *(d++));

    return r;
}

uint64_t Phi_small(uint64_t y, uint64_t c)
{
    if (!c--) return y;

    return Phi_small(y, c) - Phi_small(y / primes[c], c);
}

uint64_t pi_small(uint64_t y)
{
    uint64_t i, r = 0;

    for (i = 0; i < 8; i++) r += (primes[i] <= y);

    for (i = 21; i <= y; i += 2)
        r += i % 3 && i % 5 && i % 7 && i % 11 && i % 13 && i % 17 && i % 19;

    return r;
}

int output(int result)
{
    clock_gettime(CLOCK_REALTIME, &now);
    printf("pi(x) = %9d    real time:%9ld ns\n", result , ns(now) - ns(then));

    return 0;
}

int main(int argc, char *argv[])
{
    uint64_t b, i, j, k, limit, mask, P2, *p, start, t = 8, x = atoi(argv[1]);
    uint64_t root2 = sqrt(x), root3 = pow(x, 1./3), top = x / root3 + 1;
    uint64_t halftop = m2(top), *sieve, sieve_length = (halftop + 63) / 64;
    uint64_t i3 = 1, i5 = 2, i7 = 3, i11 = 5, i13 = 6, i17 = 8, i19 = 9;
    uint16_t Phi_3[] = { 0, 1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 8 };
    uint16_t *l, *m, Phi_4[106], Phi_5[1156];

    clock_gettime(CLOCK_REALTIME, &then);

    sieve = malloc(sieve_length * sizeof(int64_t));

    if (x < 529) return output(pi_small(x));

    for (i = 0; i < sieve_length; i++)
    {
        mask  = 0;

        mask_build( i3,  3,  2, 0x9249249249249249ULL);
        mask_build( i5,  5,  1, 0x1084210842108421ULL);
        mask_build( i7,  7,  6, 0x8102040810204081ULL);
        mask_build(i11, 11,  2, 0x0080100200400801ULL);
        mask_build(i13, 13,  1, 0x0010008004002001ULL);
        mask_build(i17, 17,  4, 0x0008000400020001ULL);
        mask_build(i19, 19, 12, 0x0200004000080001ULL);

        sieve[i] = ~mask;
    }

    limit = min(halftop, 8 * cache_size);

    for (i = 21; i < root3 + 1; i += 2)
        if (sbit(i))
            for (primes[t++] = i, j = i * i / 2; j < limit; j += i)
                word(j) &= ~bit(j);

    a = t;

    for (i = (root3 + 1) | 1; i < root2 + 1; i += 2)
        if (sbit(i)) primes[t++] = i;

    b = t;

    while (limit < halftop)
    {
        start = 2 * limit + 1, limit = min(halftop, limit + 8 * cache_size);

        for (p = &primes[8]; p < &primes[a]; p++)
            for (j = max(start / *p | 1, *p) * *p / 2; j < limit; j += *p)
                word(j) &= ~bit(j);
    }

    P2 = (a - b) * (a + b - 1) / 2;

    for (i = m2(root2); b --> a; P2 += t, i = limit)
    {
        limit = m2(x / primes[b]), j = limit & ~63;

        if (i < j)
        {
            t += popcnt((word(i)) >> (i & 63)), i = (i | 63) + 1;

            while (i < j) t += popcnt(word(i)), i += 64;

            if (i < limit) t += popcnt(word(i) & ones(limit - i));
        }
        else if (i < limit) t += popcnt((word(i) >> (i & 63)) & ones(limit - i));
    }

    if (a < 7) return output(Phi_small(x, a) + a - 1 - P2);

    a -= 7, Phi_6 = malloc(a * Phi_prec_bytes + 15016 * sizeof(int16_t));
    Phi_prec_pointer = &Phi_6[15016];

    for (i = 0; i <= 105; i++)
        Phi_4[i] = (i / 15) * 8 + Phi_3[i % 15] - Phi_3[(i + 3) / 7];

    for (i = 0; i <= 1155; i++)
        Phi_5[i] = (i / 105) * 48 + Phi_4[i % 105] - Phi_4[(i + 5) / 11];

    for (i = 1, l = Phi_6, *l++ = 0; i <= 15015; )
    {
        Phi_6_upd_3(); Phi_6_upd_2(); Phi_6_upd_1(); Phi_6_upd_2();
        Phi_6_upd_1(); Phi_6_upd_2(); Phi_6_upd_3(); Phi_6_upd_1();
    }

    for (i = 0; i <= m2(Phi_prec_max); i++)
        Phi_prec(i, 0) = Phi_6[i] - Phi_6[(i + 8) / 17];

    for (j = 1, p = &primes[7]; j < a; j++, p++)
    {
        i = 1, memcpy(&Phi_prec(0, j), &Phi_prec(0, j - 1), Phi_prec_bytes);
        l = &Phi_prec(*p / 2 + 1, j), m = &Phi_prec(m2(Phi_prec_max), j) - *p;

        while (l <= m)
            for (k = 0, t = Phi_prec(i++, j - 1); k < *p; k++) *(l++) -= t;

        t = Phi_prec(i++, j - 1);

        while (l <= m + *p) *(l++) -= t;
    }

    primes_fastdiv = malloc(a * sizeof(int64_t));

    for (i = 0, p = &primes[8]; i < a; i++, p++)
    {
        t = 96 - __builtin_clzll(*p);
        primes_fastdiv[i] = (bit(t) / *p + 1) << (64 - t);
    }

    return output(Phi(x, a) + a + 6 - P2);
}

```

This uses the Meissel-Lehmer method.

## Timings

On my machine, I'm getting roughly **5.7 milliseconds** for the combined test cases. This is on an Intel Core i7-3770 with DDR3 RAM at 1867 MHz, running openSUSE 13.2.

```
$ ./timepi '-march=native -O3' pi 1000
pi(x) =  93875448    real time:  2774958 ns
pi(x) =  66990613    real time:  2158491 ns
pi(x) =  62366021    real time:  2023441 ns
pi(x) =  34286170    real time:  1233158 ns
pi(x) =   5751639    real time:   384284 ns
pi(x) =   2465109    real time:   239783 ns
pi(x) =   1557132    real time:   196248 ns
pi(x) =      4339    real time:    60597 ns

0.00572879 s

```

Because the variance got too high, I'm using timings from within the program for the unofficial run times. This is the script that computed the average of the combined run times.

```
#!/bin/bash

all() { for j in ${a[@]}; do ./$1 $j; done; }

gcc -Wall $1 -lm -o $2 $2.c

a=(1907000000 1337000000 1240000000 660000000 99820000 40550000 24850000 41500)

all $2

r=$(seq 1 $3)

for i in $r; do all $2; done > times

awk -v it=$3 '{ sum += $6 } END { print "\n" sum / (1e9 * it) " s" }' times

rm times

```

### Official times

This time is for doing the score cases 1000 times.

```
real    0m28.006s
user    0m15.703s
sys 0m14.319s

```

## How it works

### Formula

Let \\$x\\$ be a positive integer.

Each positive integer \\$n \le x\\$ satisfies exactly one of the following conditions.

1. \\$n = 1\\$
2. \\$n\\$ is divisible by a prime number \\$p\\$ in \\$\[1, \sqrt\[3\]{x}\]\\$.
3. \\$n = pq\\$, where \\$p\\$ and \\$q\\$ are (not necessarily distinct) prime numbers in \\$(\sqrt\[3\]{x}, \sqrt\[3\]{x^2})\\$.
4. \\$n\\$ is prime and \\$n \> \sqrt\[3\]{x}\\$

Let \\$\pi(y)\\$ denote the number of primes \\$p\\$ such that \\$p \le y\\$. There are \\$\pi(x) - \pi(\sqrt\[3\]{x})\\$ numbers that fall in the fourth category.

Let \\$P\_k(y, c)\\$ denote the amount of positive integers \\$m \le y\\$ that are a product of exactly \\$k\\$ prime numbers not among the first \\$c\\$ prime numbers. There are \\$P\_2(x, \pi(\sqrt\[3\]{x}))\\$ numbers that fall in the third category.

Finally, let \\$\phi(y, c)\\$ denote the amount of positive integers \\$k \le y\\$ that are coprime to the first \\$c\\$ prime numbers. There are \\$x - \phi(x, \pi(\sqrt\[3\]{x}))\\$ numbers that fall into the second category.

Since there are \\$x\\$ numbers in all categories,

$$1 + x - \phi(x, \pi(\sqrt\[3\]{x})) + P\_2(x, \pi(\sqrt\[3\]{x})) + \pi(x) - \pi(\sqrt\[3\]{x}) = x$$

and, therefore,

$$\pi(x) = \phi(x, \pi(\sqrt\[3\]{x})) + \pi(\sqrt\[3\]{x}) - 1 - P\_2(x, \pi(\sqrt\[3\]{x}))$$

The numbers in the third category have a unique representation if we require that \\$p \le q\\$ and, therefore \\$p \le \sqrt{x}\\$. This way, the product of the primes \\$p\\$ and \\$q\\$ is in the third category if and only if \\$\sqrt\[3\]{x} \< p \le q \le \frac{x}{p}\\$, so there are \\$\pi(\frac{x}{p}) - \pi(p) + 1\\$ possible values for \\$q\\$ for a fixed value of \\$p\\$, and \\$P\_2(x, \pi(\sqrt\[3\]{x})) = \sum\_{\pi(\sqrt\[3\]{x}) \< k \le \pi(\sqrt{x})} (\pi(\frac{x}{p\_k}) - \pi(p\_k) + 1)\\$, where \\$p\_k\\$ denotes the \\$k^{\text{th}}\\$ prime number.

Finally, every positive integer \\$n \le y\\$ that is *not* coprime to the first \\$c\\$ prime numbers can be expressed in unique fashion as \\$n = p\_kf\\$, where \\$p\_k\\$ is the lowest prime factor of \\$n\\$. This way, \\$k \le c\\$, and \\$f\\$ is coprime to the first \\$k - 1\\$ primes numbers.

This leads to the recursive formula \\$\phi(y, c) = y - \sum\_{1 \le k \le c} \phi(\frac{y}{p\_k}, k - 1)\\$. In particular, the sum is empty if \\$c = 0\\$, so \\$\phi(y, 0) = y\\$.

We now have a formula that allows us to compute \\$\pi(x)\\$ by generating only the first \\$\pi(\sqrt\[3\]{x^2})\\$ prime numbers (millions vs billions).

### Algorithm

We'll need to compute \\$\pi(\frac{x}{p})\\$, where \\$p\\$ can get as low as \\$\sqrt\[3\]{x}\\$. While there are other ways to do this (like applying our formula recursively), the fastest way seems to be to enumerate all primes up to \\$\sqrt\[3\]{x^2}\\$, which can be done with the sieve of Eratosthenes.

First, we identify and store all prime numbers in \\$\[1, \sqrt{x}\]\\$, and compute \\$\pi(\sqrt\[3\]{x})\\$ and \\$\pi(\sqrt{x})\\$ at the same time. Then, we compute \\$\frac{x}{p\_k}\\$ for all \\$k\\$ in \\$(\pi(\sqrt\[3\]{x}), \pi(\sqrt{x})\]\\$, and count the primes up to each successive quotient.

Also, \\$\sum\_{\pi(\sqrt\[3\]{x}) \< k \le \pi(\sqrt{x})} (-\pi(p\_k) + 1)\\$ has the closed form \\$\frac{\pi(\sqrt\[3\]{x}) - \pi(\sqrt{x}))(\pi(\sqrt\[3\]x) + \pi(\sqrt{x}) - 1}{2}\\$, which allows us to complete the computation of \\$P\_2(x, \pi(\sqrt\[3\]{x}))\\$.

That leaves the computation of \\$\phi\\$, which is the most expensive part of the algorithm. Simply using the recursive formula would require \\$2^c\\$ function calls to compute \\$\phi(y, c)\\$.

First of all, \\$\phi(0, c) = 0\\$ for all values of \\$c\\$, so \\$\phi(y, c) = y - \sum\_{1 \le k \le c, p\_k \le y} \phi(\frac{y}{p\_k}, k - 1)\\$. By itself, this observation is already enough to make the computation feasible. This is because any number below \\$2 \cdot 10^9\\$ is smaller than the product of any ten distinct primes, so the overwhelming majority of summands vanishes.

Also, by grouping \\$y\\$ and the first \\$c'\\$ summands of the definition of \\$\phi\\$, we get the alternative formula \\$\phi(y, c) = \phi(y, c') - \sum\_{c' \< k \le c, p\_k \le y} \phi(\frac{y}{p\_k}, k - 1)\\$. Thus, precomputing \\$\phi(y, c')\\$ for a fixed \\$c'\\$ and appropriate values of \\$y\\$ saves most of the remaining function calls and the associated computations.

If \\$m\_c = \prod\_{1 \le k \le c} p\_k\\$, then \\$\phi(m\_c, c) = \varphi(m\_c)\\$, since the integers in \\$\[1, m\_c\]\\$ that are divisible by none of \\$p\_1, \cdots, p\_c\\$ are precisely those that are coprime to \\$m\_c\\$. Also, since \\$\gcd(z + m\_c, m\_c) = \gcd(z, m\_c)\\$, we have that \\$\phi(y, c) = \phi(\lfloor \frac{y}{m\_c} \rfloor m\_c, c) + \phi(y % m\_c, c) = \lfloor \frac{y}{m\_c} \rfloor \varphi(m\_c) + \phi(y % m\_c, c)\\$.

Since Euler's totient function is multiplicative, \\$\varphi(m\_c) = \prod\_{1 \le k \le c} \varphi(p\_k) = \prod\_{1 \le k \le c} (p\_k - 1)\\$, and we have an easy way to derive \\$\phi(y, c)\\$ for all \\$y\\$ by precomputing the values for only those \\$y\\$ in \\$\[0, m\_c)\\$.

Also, if we set \\$c' = c - 1\\$, we obtain \\$\phi(y, c) = \phi(y, c - 1) - \phi(\frac{y}{p\_c}, c - 1)\\$, the original definition from Lehmer's paper. This gives us a simple way to precompute \\$\phi(y, c)\\$ for increasing values of \\$c\\$.

In addition for precomputing \\$\phi(y, c)\\$ for a certain, low value of \\$c\\$, we'll also precompute it for low values of \\$y\\$, cutting the recursion short after falling below a certain threshold.

### Implementation

The previous section covers most parts of the code. One remaining, important detail is how the divisions in the function `Phi` are performed.

Since computing \\$\phi\\$ only requires dividing by the first \\$\pi(\sqrt\[3\]{x})\\$ prime numbers, we can use the `fastdiv` function instead. Rather than simply dividing an \\$y\\$ by a prime \\$p\\$, we multiply \\$y\\$ by \\$d\_p \approx \frac{2^{64}}{p}\\$ instead and recover \\$\frac{y}{p}\\$ as \\$\frac{d\_py}{2^{64}}\\$. Because of how integer multiplication is implemented on **x64**, dividing by \\$2^{64}\\$ is not required; the higher 64 bits of \\$d\_py\\$ are stored in their own register.

Note that this method requires precomputing \\$d\_p\\$, which isn't faster than computing \\$\frac{y}{p}\\$ directly. However, since we have to divide by the same primes over and over again and division is *so much slower* than multiplication, this results in an important speed-up. More details on this algorithm, as well as a formal proof, can be found in Division by Invariant Integers using Multiplication.

# Answer
> 25 votes
# C99/C++, 8.9208s (28 Feb 2016)

```
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>

uint64_t popcount( uint64_t v )
    {
    v = (v & 0x5555555555555555ULL) + ((v>>1) & 0x5555555555555555ULL);
    v = (v & 0x3333333333333333ULL) + ((v>>2) & 0x3333333333333333ULL);
    v = (v & 0x0F0F0F0F0F0F0F0FULL) + ((v>>4) & 0x0F0F0F0F0F0F0F0FULL);
    v *= 0x0101010101010101ULL;
    return v >> 56;
    }

#define PPROD  3*5*7

int primecount( int limit )
    {
    int i,j;
    int reps = (limit-1)/(64*PPROD) + 1;
    int mod_limit = reps * (64*PPROD);
    int seek_limit = (int)ceil( sqrt(limit) );
    int primecount = 0;
    int slice_count = limit/250000 + 1;

    uint8_t *buf = (uint8_t *)malloc( mod_limit/8 + seek_limit);
    int *primes = (int *)malloc(seek_limit*sizeof(int));

    // initialize a repeating bit-pattern to fill our sieve-memory with
    uint64_t v[PPROD];
    memset(v, 0, sizeof(v) );
    for(i=0;i<(64*PPROD);i++)
        for(j=2;j<=7;j++)
            if( i % j == 0 )
                v[ i >> 6 ] |= 1ULL << (i & 0x3F);

    for(i=0; i<reps; i++)
        memcpy( buf + 8*PPROD*i, v, 8*PPROD );

    // use naive E-sieve to get hold of all primes to test for
    for(i=11;i<seek_limit;i+=2)
        {
        if( (buf[i >> 3] & (1 << (i & 7)) ) == 0 )
            {
            primes[primecount++] = i;
            for(j=3*i;j<seek_limit;j += 2*i )
                buf[j >> 3] |= (1 << (j&7) );
            }
        }

    // fill up whole E-sieve. Use chunks of about 30 Kbytes
    // so that the chunk of E-sieve we're working on
    // can fit into the L1-cache.
    for(j=0;j<slice_count;j++)
        {
        int low_bound = ((uint64_t)limit * j) / slice_count;
        int high_bound = ((uint64_t)limit * (j+1)) / slice_count - 1;

        for(i=0;i<primecount;i++)
            {
            int pm = primes[i];
            // compute the first odd multiple of pm that is larger than or equal
            // to the lower bound.
            uint32_t lb2 = (low_bound + pm - 1) / pm;
            lb2 |= 1;
            if( lb2 < 3 ) lb2 = 3;
            lb2 *= pm;
            uint32_t hb2 = (high_bound / pm) * pm;

            uint32_t kt1 = ((lb2 + 2*pm) >> 3) - (lb2 >> 3);
            uint32_t kt2 = ((lb2 + 4*pm) >> 3) - (lb2 >> 3);
            uint32_t kt3 = ((lb2 + 6*pm) >> 3) - (lb2 >> 3);

            uint32_t kx0 = 1 << (lb2 & 7);
            uint32_t kx1 = 1 << ((lb2 + 2*pm) & 7);
            uint32_t kx2 = 1 << ((lb2 + 4*pm) & 7);
            uint32_t kx3 = 1 << ((lb2 + 6*pm) & 7);

            uint8_t *lb3 = buf + (lb2 >> 3);
            uint8_t *hb3 = buf + (hb2 >> 3);

            uint8_t *kp;
            for(kp=lb3; kp<=hb3; kp+=pm)
                {
                kp[0]   |= kx0;
                kp[kt1] |= kx1;
                kp[kt2] |= kx2;
                kp[kt3] |= kx3;
                }
            }
        }

    // flag tail elements to exclude them from prime-counting.
    for(i=limit;i<mod_limit;i++)
        buf[i >> 3] |= 1 << (i&7);

    int sum = 0;
    uint64_t *bufx = (uint64_t *)buf;

    for(i=0;i<mod_limit>>6;i++)
        sum += popcount( bufx[i] );

    free(buf);
    free(primes);

    return mod_limit - sum + 3;
    }

int main( int argc, char **argv)
    {
    if( argc != 2 )
        {
        printf("Please provide an argument\n");
        exit(1);
        }

    int limit = atoi( argv[1] );
    if( limit < 3 || limit > 2000000000 )
        {
        printf("Argument %d out of range\n", limit );
        exit(1);
        }

    printf("%d\n", primecount(limit) );
    }

```

A bitmap-based sieve-of-erastothenes implementation. It performs the following steps:

1. First, generate a repeating bit-pattern to fill the sieve with, that covers multiples of 2,3,5,7
2. Next, use the sieve method to generate an array of all primes smaller than sqrt(n)
3. Next, use the prime list from the previous step to write into the sieve. This is done on chunks of the sieve that are approximately L1-cache-sized, so that the sieve processing doesn't constantly thrash the L1 cache; this seems to bring about a 5x speedup over not chunking.
4. Finally, perform a bit-count.

Compiled with `gcc primecount.c -O3 -lm -Wall` and run on ubuntu 15.10 (64-bit) on an i7-4970k, it takes about 2.2 seconds for the full set of score cases. The running time is dominated by step 3; this could be multithreaded if desired, since the chunks are independent; this would require some care to ensure that chunk boundaries are suitably aligned.

It allocates slightly more memory than strictly needed for the sieve; this makes room for some end-of-buffer overrun, which is necessary for the loop unrolling in step 3 to work properly.

**Official times**

```
real    0m8.934s
user    0m8.795s
sys 0m0.150s

real    0m8.956s
user    0m8.818s
sys 0m0.150s

real    0m8.907s
user    0m8.775s
sys 0m0.145s

real    0m8.904s
user    0m8.775s
sys 0m0.141s

real    0m8.902s
user    0m8.783s
sys 0m0.132s

real    0m9.087s
user    0m8.923s
sys 0m0.176s

real    0m8.905s
user    0m8.778s
sys 0m0.140s

real    0m9.005s
user    0m8.859s
sys 0m0.158s

real    0m8.911s
user    0m8.789s
sys 0m0.135s

real    0m8.907s
user    0m8.781s
sys 0m0.138s

```

# Answer
> 15 votes
# Java, 25,725.315 seconds on this machine

*This is not going to win*, I just wanted to post an answer that does not use any sieves.

**UPDATE:** This is currently ranked at about 150,440.4386 times slower than the leading score. Go up-vote them, their answer is awesome.

Byte code:

```
0000000: cafe babe 0000 0034 0030 0a00 0900 1709  .......4.0......
0000010: 0018 0019 0a00 1a00 1b0a 0008 001c 0a00  ................
0000020: 1d00 1e0a 0008 001f 0a00 2000 2107 0022  .......... .!.."
0000030: 0700 2301 0006 3c69 6e69 743e 0100 0328  ..#...<init>...(
0000040: 2956 0100 0443 6f64 6501 000f 4c69 6e65  )V...Code...Line
0000050: 4e75 6d62 6572 5461 626c 6501 0004 6d61  NumberTable...ma
0000060: 696e 0100 1628 5b4c 6a61 7661 2f6c 616e  in...([Ljava/lan
0000070: 672f 5374 7269 6e67 3b29 5601 0008 6e75  g/String;)V...nu
0000080: 6d50 7269 6d65 0100 0428 4929 4901 000d  mPrime...(I)I...
0000090: 5374 6163 6b4d 6170 5461 626c 6501 0007  StackMapTable...
00000a0: 6973 5072 696d 6501 0004 2849 295a 0100  isPrime...(I)Z..
00000b0: 0a53 6f75 7263 6546 696c 6501 0006 452e  .SourceFile...E.
00000c0: 6a61 7661 0c00 0a00 0b07 0024 0c00 2500  java.......$..%.
00000d0: 2607 0027 0c00 2800 290c 0010 0011 0700  &..'..(.).......
00000e0: 2a0c 002b 002c 0c00 1300 1407 002d 0c00  *..+.,.......-..
00000f0: 2e00 2f01 0001 4501 0010 6a61 7661 2f6c  ../...E...java/l
0000100: 616e 672f 4f62 6a65 6374 0100 106a 6176  ang/Object...jav
0000110: 612f 6c61 6e67 2f53 7973 7465 6d01 0003  a/lang/System...
0000120: 6f75 7401 0015 4c6a 6176 612f 696f 2f50  out...Ljava/io/P
0000130: 7269 6e74 5374 7265 616d 3b01 0011 6a61  rintStream;...ja
0000140: 7661 2f6c 616e 672f 496e 7465 6765 7201  va/lang/Integer.
0000150: 0008 7061 7273 6549 6e74 0100 1528 4c6a  ..parseInt...(Lj
0000160: 6176 612f 6c61 6e67 2f53 7472 696e 673b  ava/lang/String;
0000170: 2949 0100 136a 6176 612f 696f 2f50 7269  )I...java/io/Pri
0000180: 6e74 5374 7265 616d 0100 0770 7269 6e74  ntStream...print
0000190: 6c6e 0100 0428 4929 5601 000e 6a61 7661  ln...(I)V...java
00001a0: 2f6c 616e 672f 4d61 7468 0100 0473 7172  /lang/Math...sqr
00001b0: 7401 0004 2844 2944 0021 0008 0009 0000  t...(D)D.!......
00001c0: 0000 0004 0001 000a 000b 0001 000c 0000  ................
00001d0: 001d 0001 0001 0000 0005 2ab7 0001 b100  ..........*.....
00001e0: 0000 0100 0d00 0000 0600 0100 0000 0100  ................
00001f0: 0900 0e00 0f00 0100 0c00 0000 2c00 0300  ............,...
0000200: 0100 0000 10b2 0002 2a03 32b8 0003 b800  ........*.2.....
0000210: 04b6 0005 b100 0000 0100 0d00 0000 0a00  ................
0000220: 0200 0000 0300 0f00 0400 0a00 1000 1100  ................
0000230: 0100 0c00 0000 6600 0200 0300 0000 2003  ......f....... .
0000240: 3c03 3d1c 1aa2 0018 1b1c b800 0699 0007  <.=.............
0000250: 04a7 0004 0360 3c84 0201 a7ff e91b ac00  .....`<.........
0000260: 0000 0200 0d00 0000 1600 0500 0000 0600  ................
0000270: 0200 0700 0900 0800 1800 0700 1e00 0900  ................
0000280: 1200 0000 1800 04fd 0004 0101 5001 ff00  ............P...
0000290: 0000 0301 0101 0002 0101 fa00 0700 0a00  ................
00002a0: 1300 1400 0100 0c00 0000 9700 0300 0300  ................
00002b0: 0000 4c1a 05a2 0005 03ac 1a05 9f00 081a  ..L.............
00002c0: 06a0 0005 04ac 1a05 7099 0009 1a06 709a  ........p.....p.
00002d0: 0005 03ac 1a87 b800 078e 0460 3c10 063d  ...........`<..=
00002e0: 1c1b a300 1b1a 1c04 6470 9900 0b1a 1c04  ........dp......
00002f0: 6070 9a00 0503 ac84 0206 a7ff e604 ac00  `p..............
0000300: 0000 0200 0d00 0000 2200 0800 0000 0c00  ........".......
0000310: 0700 0d00 1300 0e00 2100 0f00 2a00 1000  ........!...*...
0000320: 3200 1100 4400 1000 4a00 1200 1200 0000  2...D...J.......
0000330: 1100 0907 0901 0b01 fd00 0b01 0114 01fa  ................
0000340: 0005 0001 0015 0000 0002 0016            ............

```

Source Code:

```
public class E {
    public static void main(String[]args){
        System.out.println(numPrime(Integer.parseInt(args[0])));
    }
    private static int numPrime(int max) {
        int toReturn = 0;
        for (int i = 0; i < max; i++)
            toReturn += (isPrime(i))?1:0;
        return toReturn;
    }
    private static boolean isPrime(int n) {
            if(n < 2) return false;
            if(n == 2 || n == 3) return true;
            if(n%2 == 0 || n%3 == 0) return false;
            int sqrtN = (int)Math.sqrt(n)+1;
            for(int i = 6; i <= sqrtN; i += 6)
                if(n%(i-1) == 0 || n%(i+1) == 0) return false;
            return true;
    }
}

```

Turns out the optimizer was, in fact, increasing the time taken. \>.\> Dammit.

Input below 1000 appears to take .157s average time on my computer (likely due to class loading ಠ\_ಠ), but past about 1e7 it gets fussy.

Timing list:

```
> time java E 41500;time java E 24850000;time java E 40550000;time java E 99820000;time java E 660000000;time java E 1240000000;time java E 1337000000;time java E 1907000000
4339

real    0m0.236s
user    0m0.112s
sys     0m0.024s
1557132

real    0m8.842s
user    0m8.784s
sys     0m0.060s
2465109

real    0m18.442s
user    0m18.348s
sys     0m0.116s
5751639

real    1m15.642s
user    1m8.772s
sys     0m0.252s
34286170

real    40m35.810s
user    16m5.240s
sys     0m5.820s
62366021

real    104m12.628s
user    39m32.348s
sys     0m13.584s
66990613

real    110m22.064s
user    42m28.092s
sys     0m11.320s
93875448

real    171m51.650s
user    68m39.968s
sys     0m14.916s
```

# Answer
> 15 votes
# Python 2 (PyPy 4.0), 2.36961s (Feb 29 2016)

```
def Phi(m, b):
    if not b:
        return m
    if not m:
        return 0
    if m >= 800:
        return Phi(m, b - 1) - Phi(m // primes[b - 1], b - 1)
    t = b * 800 + m
    if not Phi_memo[t]:
        Phi_memo[t] =  Phi(m, b - 1) - Phi(m // primes[b - 1], b - 1)
    return Phi_memo[t]

x = int(input())

if x < 6:
    print [0, 0, 1, 2, 2, 3][x]
    exit()

root2 = int(x ** (1./2))
root3 = int(x ** (1./3))
top = x // root3 + 1
sieve = [0, 0] + [1] * (top - 2)
pi = [0, 0]
primes = []
t = 0

for i in range(2, top):
    if sieve[i] == 1:
        t += 1
        primes.append(i)
        sieve[i::i] = [0] * len(sieve[i::i])
    pi.append(t)

a, b = pi[root3 + 1], pi[root2 + 1]
Phi_memo = [0] * ((a + 1) * 800)

print Phi(x, a) + a - 1 - sum(pi[x // p] - pi[p] + 1 for p in primes[a:b])

```

This uses the Meissel-Lehmer method.

### Timings

```
$ time for i in 1.907e9 1.337e9 1.24e9 6.6e8 9.982e7 4.055e7 2.485e7 41500
> do pypy pi.py <<< $i; done
93875448
66990613
62366021
34286170
5751639
2465109
1557132
4339

real    0m1.696s
user    0m1.360s
sys     0m0.332s

```

**Official times**

Since there was another answer with a similar time, I opted to get more precise results. I timed this 100 times. The score is the following time divided by 100.

```
real    3m56.961s
user    3m38.802s
sys 0m18.512s

```

# Answer
> 11 votes
# Rust, 0.37001 sec (12 June 2016)

About 10 times slower than slower than Dennis' `C` answer, but 10 times faster than his Python entry. This answer is made possible by @Shepmaster and @Veedrac who helped improve it on Code Review. It is taken verbatim from @Veedrac's post.

```
use std::env;

const EMPTY: usize = std::usize::MAX;
const MAX_X: usize = 800;

fn main() {
    let args: Vec<_> = env::args().collect();
    let x: usize = args[1].trim().parse().expect("expected a number");

    let root = (x as f64).sqrt() as usize;
    let y = (x as f64).powf(0.3333333333333) as usize + 1;

    let sieve_size = x / y + 2;
    let mut sieve = vec![true; sieve_size];
    let mut primes = vec![0; sieve_size];
    sieve[0] = false;
    sieve[1] = false;

    let mut a = 0;
    let mut num_primes = 1;

    let mut num_primes_smaller_root = 0;

    // find all primes up to x/y ~ x^2/3 aka sieve_size
    for i in 2..sieve_size {
        if sieve[i] {
            if i <= root {
                if i <= y {
                    a += 1;
                }
                num_primes_smaller_root += 1;
            }

            primes[num_primes] = i;
            num_primes += 1;
            let mut multiples = i;
            while multiples < sieve_size {
                sieve[multiples] = false;
                multiples += i;
            }
        }
    }

    let interesting_primes = primes[a + 1..num_primes_smaller_root + 1].iter();

    let p_2 =
        interesting_primes
        .map(|ip| primes.iter().take_while(|&&p| p <= x / ip).count())
        .enumerate()
        .map(|(i, v)| v - 1 - i - a)
        .fold(0, |acc, v| acc + v);

    let mut phi_results = vec![EMPTY; (a + 1) * MAX_X];
    println!("pi({}) = {}", x, phi(x, a, &primes, &mut phi_results) + a - 1 - p_2);
}

fn phi(x: usize, b: usize, primes: &[usize], phi_results: &mut [usize]) -> usize {
    if b == 0 {
        return x;
    }

    if x < MAX_X && phi_results[x + b * MAX_X] != EMPTY {
        return phi_results[x + b * MAX_X];
    }

    let value = phi(x, b - 1, primes, phi_results) - phi(x / primes[b], b - 1, primes, phi_results);
    if x < MAX_X {
        phi_results[x + b * MAX_X] = value;
    }
    value
}

```

Timed with: `time ./time.sh` where `time.sh` looks like:

```
#!/bin/bash

a=(1907000000 1337000000 1240000000 660000000 99820000 40550000 24850000 41500)

for i in {0..100}; do
    for j in ${a[@]}; do
        ./target/release/pi_n $j  > /dev/null;
    done;
done;

```

Here is the output.

```
[me@localhost pi_n]$ time ./time.sh

real    0m37.011s
user    0m34.752s
sys 0m2.410s

```

# Answer
> 8 votes
# Node.js (JavaScript/ES6), 83.549s (11 Nov 2016)

```
var n=process.argv[2]*1,r=new Uint8Array(n),p=0,i=1,j
while(++i<=n){
  if(r[i]===0){
    for(j=i*i;j<=n;j+=i){r[j]=1}
    p+=1
  }
}
console.log(p)

```

Finally got around to remaking this, and it's both smaller/simpler and MUCH faster than before. Rather than a slower brute force method, it utilizes the Sieve of Eratosthenes alongside more efficient data structures, so that it is now able to actually finish in a respectable time (as far as I can find on the internet, it's the fastest JS prime count function out there).

Some demo times (i7-3770k):

```
10^4 (10,000) => 0.001 seconds
10^5 (100,000) => 0.003 seconds
10^6 (1,000,000) => 0.009 seconds
10^7 (10,000,000) => 0.074 seconds
10^8 (100,000,000) => 1.193 seconds
10^9 (1,000,000,000) => 14.415 seconds

```

# Answer
> 6 votes
# C++11, 22.6503s (28 Feb 2016)

Compile with `g++ -O2 -m64 -march=native -ftree-vectorize -std=c++11 numprimes.cpp`. **These options are important.** You also need to have Boost installed. On Ubuntu this is available by installing `libboost-all-dev`.

If you are on Windows I can recommend installing `g++` and Boost through MSYS2. I have written a nice tutorial on how to install MSYS2. After following the tutorial you can install Boost using `pacman -Sy `pacman -Ssq boost``.

```
#include <cmath>
#include <cstdint>
#include <iostream>
#include <vector>
#include <boost/dynamic_bitset.hpp>

uint64_t num_primes(uint64_t n) {
    // http://stackoverflow.com/questions/4643647/fast-prime-factorization-module
    uint64_t pi = (n >= 2) + (n >= 3);
    if (n < 5) return pi;

    n += 1;
    uint64_t correction = n % 6 > 1;
    uint64_t wheels[6] = { n, n - 1, n + 4, n + 3, n + 2, n + 1 };
    uint64_t limit = wheels[n % 6];

    boost::dynamic_bitset<> sieve(limit / 3);
    sieve.set();
    sieve[0] = false;

    for (uint64_t i = 0, upper = uint64_t(std::sqrt(limit))/3; i <= upper; ++i) {
        if (sieve[i]) {
            uint64_t k = (3*i + 1) | 1;
            for (uint64_t j = (k*k) / 3;                   j < limit/3; j += 2*k) sieve[j] = false;
            for (uint64_t j = (k*k + 4*k - 2*k*(i & 1))/3; j < limit/3; j += 2*k) sieve[j] = false;
        }
    }

    pi += sieve.count();
    for (uint64_t i = limit / 3 - correction; i < limit / 3; ++i) pi -= sieve[i];

    return pi;
}

int main(int argc, char** argv) {
    if (argc <= 1) {
        std::cout << "Usage: " << argv[0] << " n\n";
        return 0;
    }

    std::cout << num_primes(std::stoi(argv[1])) << "\n";
    return 0;
}

```

On my machine this runs in 4.8 seconds for 1907000000 (1.9e9).

<sup>The code above was repurposed from my personal C++ library, so I had a head start.</sup>

**Official times**

```
real    0m22.760s
user    0m22.704s
sys 0m0.080s

real    0m22.854s
user    0m22.800s
sys 0m0.077s

real    0m22.742s
user    0m22.700s
sys 0m0.066s

real    0m22.484s
user    0m22.450s
sys 0m0.059s

real    0m22.653s
user    0m22.597s
sys 0m0.080s

real    0m22.665s
user    0m22.602s
sys 0m0.088s

real    0m22.528s
user    0m22.489s
sys 0m0.062s

real    0m22.510s
user    0m22.474s
sys 0m0.060s

real    0m22.819s
user    0m22.759s
sys 0m0.084s

real    0m22.488s
user    0m22.459s
sys 0m0.053s

```

# Answer
> 3 votes
# C++, 2.47215s (29 Feb 2016)

This is a (sloppy) multi-threaded version of my other answer.

```
#include <cstdint>
#include <vector>
#include <iostream>
#include <limits>
#include <cmath>
#include <array>
// uses posix ffsll
#include <string.h>
#include <algorithm>
#include <thread>

constexpr uint64_t wheel_width = 2;
constexpr uint64_t buf_size = 1<<(10+6);
constexpr uint64_t dtype_width = 6;
constexpr uint64_t dtype_mask = 63;
constexpr uint64_t buf_len = ((buf_size*wheel_width)>>dtype_width);
constexpr uint64_t seg_len = 6*buf_size;
constexpr uint64_t limit_i_max = 0xfffffffe00000001ULL;

typedef std::vector<uint64_t> buf_type;

void mark_composite(buf_type& buf, uint64_t prime,
                    std::array<uint64_t, 2>& poff,
                    uint64_t seg_start, uint64_t max_j)
{
  const auto p = 2*prime;
  for(uint64_t k = 0; k < wheel_width; ++k)
  {
    for(uint64_t j = 2*poff[k]+(k==0); j < max_j; j += p)
    {
      buf[(j-seg_start)>>dtype_width] |= 1ULL << (j & dtype_mask);
      poff[k] += prime;
    }
  }
}

struct prime_counter
{
  buf_type buf;
  uint64_t n;
  uint64_t seg_a, seg_b;
  uint64_t nj;
  uint64_t store_max;
  uint64_t& store_res;

  prime_counter(uint64_t n, uint64_t seg_a, uint64_t seg_b, uint64_t nj, uint64_t store_max,
                uint64_t& store_res) :
    buf(buf_len), n(n), nj(nj), seg_a(seg_a), seg_b(seg_b),
    store_max(store_max), store_res(store_res)
  {}

  prime_counter(const prime_counter&) = default;
  prime_counter(prime_counter&&) = default;

  prime_counter& operator =(const prime_counter&) = default;
  prime_counter& operator =(prime_counter&&) = default;

  void operator()(uint64_t nsmall_segs,
                  const std::vector<uint64_t>& primes,
                  std::vector<std::array<uint64_t, 2> > poffs)
  {
    uint64_t res = 0;
    // no new prime added portion
    uint64_t seg_start = buf_size*wheel_width*seg_a;
    uint64_t seg_min = seg_len*seg_a+5;

    if(seg_a > nsmall_segs)
    {
      uint64_t max_j = buf_size*wheel_width*nsmall_segs+(seg_a-nsmall_segs)*(buf_len<<dtype_width);
      for(size_t k = 0; k < wheel_width; ++k)
      {
        for(uint64_t i = 0; i < poffs.size() && max_j >= (2*poffs[i][k]+(k==0)); ++i)
        {
          // adjust poffs
          // TODO: might be a more efficient way
          auto w = (max_j-(2*poffs[i][k]+(k==0)));
          poffs[i][k] += primes[i]*(w/(2*primes[i]));
          if(w % (2*primes[i]) != 0)
          {
            poffs[i][k]+=primes[i];// += primes[i]*(w/(2*primes[i])+1);
          }
          /*else
          {

          }*/
        }
      }
    }

    for(uint64_t seg = seg_a; seg < seg_b; ++seg)
    {
      std::fill(buf.begin(), buf.end(), 0);
      const uint64_t limit_i = std::min<uint64_t>((((seg_len+seg_min) >= limit_i_max) ?
                                                   std::numeric_limits<uint32_t>::max() :
                                                   ceil(sqrt(seg_len+seg_min))),
                                                  store_max);
      uint64_t max_j = std::min(seg_start+(buf_len<<dtype_width), nj);
      for(uint64_t i = 0; i < primes.size() && primes[i] <= limit_i; ++i)
      {
        mark_composite(buf, primes[i], poffs[i], seg_start, max_j);
      }
      // sieve
      uint64_t val;
      const uint64_t stop = std::min(seg_min+seg_len, n);
      for(uint64_t i = ffsll(~(buf[0]))-((~buf[0]) != 0)+64*((~buf[0]) == 0);
          (val = 6ULL*(i>>1)+seg_min+2ULL*(i&1ULL)) < stop;)
      {
        if(!(buf[i>>dtype_width] & (1ULL << (i & dtype_mask))))
        {
          ++res;
          ++i;
        }
        else
        {
          uint64_t mask = buf[i>>dtype_width]>>(i&dtype_mask);
          const int64_t inc = ffsll(~mask)-((~mask) != 0)+64*((~mask) == 0);
          i += inc;
        }
      }
      seg_min += seg_len;
      seg_start += buf_size*wheel_width;
    }
    store_res = res;
  }
};

uint64_t num_primes(uint64_t n)
{
  uint64_t res = (n >= 2) + (n >= 3);
  if(n >= 5)
  {
    buf_type buf(buf_len);
    // compute and store primes < sqrt(n)
    const uint64_t store_max = ceil(sqrt(n));

    // only primes >= 5
    std::vector<uint64_t> primes;
    std::vector<std::array<uint64_t, 2> > poffs;
    primes.reserve(ceil(1.25506*store_max/log(store_max)));
    poffs.reserve(ceil(1.25506*store_max/log(store_max)));
    uint64_t seg_start = 0;
    uint64_t seg_min = 5;
    const uint64_t num_segs = 1+(n-seg_min)/seg_len;
    const uint64_t nj = (n-seg_min)/3+1;
    // compute how many small segments there are
    const uint64_t nsmall_segs = 1+(store_max-seg_min)/seg_len;
    for(uint64_t seg = 0; seg < nsmall_segs; ++seg)
    {
      std::fill(buf.begin(), buf.end(), 0);
      // mark off small primes
      const uint64_t limit_i = std::min<uint64_t>((((seg_len+seg_min) >= limit_i_max) ?
                                                   std::numeric_limits<uint32_t>::max() :
                                                   ceil(sqrt(seg_len+seg_min))),
                                                  store_max);
      uint64_t max_j = std::min(seg_start+(buf_len<<dtype_width), nj);
      for(uint64_t i = 0; i < primes.size() && primes[i] <= limit_i; ++i)
      {
        mark_composite(buf, primes[i], poffs[i], seg_start, max_j);
      }
      // sieve
      uint64_t val;
      const uint64_t stop = std::min(seg_min+seg_len, n);
      for(uint64_t i = ffsll(~(buf[0]))-((~buf[0]) != 0)+64*((~buf[0]) == 0);
            (val = 6ULL*(i>>1)+seg_min+2ULL*(i&1ULL)) < stop;)
      {
        if(!(buf[i>>dtype_width] & (1ULL << (i & dtype_mask))))
        {
          if(val <= store_max)
          {
            // add prime and poffs
            primes.push_back(val);
            poffs.emplace_back();
            poffs.back()[0] = (val*val-1)/6-1;
            if(i&1)
            {
              // 6n+1 prime
              poffs.back()[1] = (val*val+4*val-5)/6;
            }
            else
            {
              // 6n+5 prime
              poffs.back()[1] = (val*val+2*val-5)/6;
            }
            // mark-off multiples
            mark_composite(buf, val, poffs.back(), seg_start, max_j);
          }
          ++res;
          ++i;
        }
        else
        {
          uint64_t mask = buf[i>>dtype_width]>>(i&dtype_mask);
          const int64_t inc = ffsll(~mask)-((~mask) != 0)+64*((~mask) == 0);
          i += inc;
        }
      }
      seg_min += seg_len;
      seg_start += buf_size*wheel_width;
    }
    // multi-threaded sieving for remaining segments
    std::vector<std::thread> workers;
    auto num_workers = std::min<uint64_t>(num_segs-nsmall_segs, std::thread::hardware_concurrency());
    std::vector<uint64_t> store_reses(num_workers);

    workers.reserve(num_workers);
    auto num_segs_pw = ceil((num_segs-nsmall_segs)/static_cast<double>(num_workers));
    for(size_t i = 0; i < num_workers; ++i)
    {
      workers.emplace_back(prime_counter(n, nsmall_segs+i*num_segs_pw,
                                         std::min<uint64_t>(nsmall_segs+(i+1)*num_segs_pw,
                                                            num_segs),
                                         nj, store_max, store_reses[i]),
                           nsmall_segs, primes, poffs);
    }
    for(size_t i = 0; i < num_workers; ++i)
    {
      workers[i].join();
      res += store_reses[i];
    }
  }
  return res;
}

int main(int argc, char** argv)
{
  if(argc <= 1)
  {
    std::cout << "usage: " << argv[0] << " n\n";
    return -1;
  }
  std::cout << num_primes(std::stoll(argv[1])) << '\n';
}

```

Uses a segmented sieve of Eratosthenes with a wheel factorization of 6 to skip all multiples of 2/3. Makes use of the POSIX `ffsll` to skip consecutive composite values.

To compile:

```
g++ -std=c++11 -o sieve_mt -O3 -march=native -pthread sieve_mt.cpp

```

## unofficial timings

Timed with an Intel i5-6600k on Ubuntu 15.10, the 1907000000 case took `0.817s`.

**Official times**

To get more precise times, I timed this 100 times, then divided the time by 100.

```
real    4m7.215s
user    23m54.086s
sys 0m1.239s

```

# Answer
> 3 votes
# TypeScript, 0.1s (Oct, 2021)

It is never too late to post a good solution, especially when TypeScript code outperforms most of the C++ implementations published here earlier :)

This implementation finishes all test cases in **102ms** on my machine:

```
import {countPrimes} from 'prime-lib';

const inputs = [
    1907000000,
    1337000000,
    1240000000,
    660000000,
    99820000,
    40550000,
    24850000,
    41500
];

const start = Date.now();
inputs.forEach(i => {
    countPrimes(i);
});
console.log(Date.now() - start); //=> 102ms

```

Here's implementation of `countPrimes` in the library that I wrote.

But I'm also posting the current code from the link here, just in case:

```
function countPrimes(x: number): number {
    if (x < 6) {
        if (x < 2) {
            return 0;
        }
        return [1, 2, 2, 3][x - 2];
    }
    const root2 = Math.floor(Math.sqrt(x));
    const root3 = Math.floor(x ** 0.33333);
    const top = Math.floor(x / root3) + 1;
    const {primes, pi} = soeCalc(top + 2);
    const a = pi[root3 + 1], b = pi[root2 + 1];
    let sum = 0;
    for (let i = a; i < b; ++i) {
        const p = primes[i];
        sum += pi[Math.floor(x / p)] - pi[p] + 1;
    }
    return Phi(x, a, primes) + a - 1 - sum;
}

function soeCalc(x: number): { primes: Uint32Array, pi: Uint32Array } {
    // Pierre Dusart's maximum primes: π(x) < (x/ln x)(1 + 1.2762/ln x)
    const maxPrimes = Math.ceil(x / Math.log(x) * (1 + 1.2762 / Math.log(x)));
    const primes = new Uint32Array(maxPrimes);
    const upperLimit = Math.sqrt(x);
    const bmc = Math.ceil(x / 32); // bitmask compression
    const pi = new Uint32Array(x);
    const arr = new Uint32Array(bmc);
    arr.fill(0xFFFF_FFFF);
    for (let i = 2; i <= upperLimit; i++) {
        if (arr[i >>> 5] & 1 << i % 32) {
            for (let j = i * i; j < x; j += i) {
                arr[j >>> 5] &= ~(1 << j % 32);
            }
        }
    }
    let count = 0;
    for (let i = 2; i < x; i++) {
        if (arr[i >>> 5] & 1 << i % 32) {
            primes[count] = i;
            count++;
        }
        pi[i] = count;
    }
    return {primes, pi};
}

function Phi(m1: number, b1: number, p: Uint32Array): number {
    const fts = 800; // factorial table size
    const maxMem = b1 * fts + Math.min(m1, fts) + 1;
    const memo = new Uint16Array(maxMem);
    return function loop(m: number, b: number): number {
        if (b === 0 || m === 0) {
            return m;
        }
        if (m >= fts) {
            return loop(m, --b) - loop(Math.floor(m / p[b]), b);
        }
        const t = b * fts + m;
        if (!memo[t]) {
            memo[t] = loop(m, --b) - loop(Math.floor(m / p[b]), b);
        }
        return memo[t];
    }(m1, b1);
}

```

**Tested on:**

* OS: Windows 10 Pro
* CPU: Ryzen 9 5900X 12-Core Processor, 3693Mhz
* NodeJS: v14.18.1

# Answer
> 2 votes
# C, 2m42.7254s (Feb 28 2016)

Save as `pi.c`, compile as `gcc -o pi pi.c`, run as `./pi <arg>`:

```
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

unsigned char p[2000000001];

int main(int argc, char **argv)
{
        unsigned int n, c, i, j;

        n = atoi(argv[1]);
        memset(p, 1, n + 1);

        p[1] = p[0] = 0;

        for (i = 2, c = 0; i <= n; i++)
        {
                if (p[i])
                {
                        c++;
                        for (j = i + i; j <= n; j += i)
                                p[j] = 0;
                }
        }

        printf("%d: %d\n", n, c);

        return 0;
}

```

Needs a lot of memory to run! If your hardware can't spare up to two gigabytes of real memory, then the program will either crash or run very slowly because of VMM and HD thrashing.

Approximate timing on my hardware is 1.239×10<sup>-8</sup>·n<sup>1.065</sup> s. For example, an input of n = 2×10<sup>9</sup> takes about 100 s to run.

**Official times**

```
real    2m42.657s
user    2m42.065s
sys 0m0.757s

real    2m42.947s
user    2m42.400s
sys 0m0.708s

real    2m42.827s
user    2m42.282s
sys 0m0.703s

real    2m42.800s
user    2m42.300s
sys 0m0.665s

real    2m42.562s
user    2m42.050s
sys 0m0.675s

real    2m42.788s
user    2m42.192s
sys 0m0.756s

real    2m42.631s
user    2m42.074s
sys 0m0.720s

real    2m42.658s
user    2m42.115s
sys 0m0.707s

real    2m42.710s
user    2m42.219s
sys 0m0.657s

real    2m42.674s
user    2m42.110s
sys 0m0.730s

```

# Answer
> 2 votes
# Python 3

```
import sys

sys.setrecursionlimit(sys.maxsize)

n = int(sys.argv[-1])

if n < 4:
    print(0 if n < 2 else n-1)
    exit()

p = [0, 0] + [True] * n

i = 0
while i < pow(n, 0.5):
    if p[i]:
        j = pow(i, 2)
        while j < n:
            p[j] = False
            j += i
    i += 1

print(sum(p) - 2)

```

Uses the Sieve of Eratosthenes. Runs at an average of `8.775s` where `n = 10^7`. To time, I used the builtin `time` command. For example:

```
$ time python3 test.py 90
24

real    0m0.045s
user    0m0.031s
 sys    0m0.010s

```

# Answer
> 2 votes
# Julia, 1m 21.1329s

I'd like to come up with something a little faster, but for now here's a rather naïve implementation of the Sieve of Eratosthenes.

```
function eratos(n::Int64)
    sieve = trues(n)
    sieve[1] = false
    for p = 2:isqrt(n)
        @inbounds sieve[p] || continue
        for i = 2:n÷p
            @inbounds sieve[p*i] = false
        end
    end
    return sum(sieve)
end

const x = parse(Int64, ARGS[1])

println(eratos(x))

```

Get the latest version of Julia for your system here. Make sure the Julia executable is in your path. Save the code as `sieve.jl` and run from the command line like `julia sieve.jl N`, where `N` is the input.

**Official times**

```
real    1m21.227s
user    1m20.755s
sys 0m0.576s

real    1m20.944s
user    1m20.426s
sys 0m0.640s

real    1m21.052s
user    1m20.581s
sys 0m0.573s

real    1m21.328s
user    1m20.862s
sys 0m0.570s

real    1m21.253s
user    1m20.780s
sys 0m0.588s

real    1m20.925s
user    1m20.460s
sys 0m0.576s

real    1m21.011s
user    1m20.512s
sys 0m0.601s

real    1m21.011s
user    1m20.550s
sys 0m0.564s

real    1m20.875s
user    1m20.409s
sys 0m0.569s

real    1m21.703s
user    1m21.088s
sys 0m0.701s

```

# Answer
> 2 votes
# Java, 42.663122s\* (Mar 3 2016)

**this was timed internally by the program (on the OP's computer though)*

```
public class PrimeCounter
{
public static final String START_CODE="=",
TEST_FORMAT="Input = %d , Output = %d , calculated in %f seconds%n",
PROMPT="Enter numbers to compute pi(x) for (Type \""+START_CODE+"\" to start):%n",
WAIT="Calculating, please wait...%n",
WARNING="Probably won't work with values close to or more than 2^31%n",
TOTAL_OUTPUT_FORMAT="Total time for all inputs is %f seconds%n";
public static final int NUM_THREADS=16,LOW_LIM=1,HIGH_LIM=1<<28;
private static final Object LOCK=new Lock();
private static final class Lock{}
/**
 * Generates and counts primes using an optimized but naive iterative algorithm.
 * Uses MultiThreading for arguments above LOW_LIM
 * @param MAX : argument x for pi(x), the limit to which to generate numbers.
 */
public static long primeCount(long MAX){
    long ctr=1;
    if(MAX<1<<7){
        for(long i=3;i<=MAX;i+=2){
            if(isPrime(i))++ctr;
        }
    }else{
        long[] counts=new long[NUM_THREADS];
        for(int i=0;i<NUM_THREADS;++i){
            counts[i]=-1;
        }
        long range=Math.round((double)MAX/NUM_THREADS);
        for(int i=0;i<NUM_THREADS;++i){
            long start=(i==0)?3:i*range+1,end=(i==NUM_THREADS-1)?MAX:(i+1)*range;
            final int idx=i;
            new Thread(new Runnable(){
                    public void run(){
                        for(long j=start;j<=end;j+=2){
                            if(isPrime(j))++counts[idx];
                        }
                    }
                }).start();
        }
        synchronized(LOCK){
            while(!completed(counts)){
                try{
                    LOCK.wait(300);}catch(InterruptedException ie){}
            }
            LOCK.notifyAll();
        }
        for(long count:counts){
            ctr+=count;
        }
        ctr+=NUM_THREADS;
    }
    return ctr;
}

/**
 * Checks for completion of threads
 * @param array : The array containing the completion data
 */
private static boolean completed(long[] array){
    for(long i:array){
        if(i<0)return false;
    }return true;
}

/**
 * Checks if the parameter is prime or not.
 * 2,3,5,7 are hardcoded as factors.
 * @param n : the number to check for primality
 */
private static boolean isPrime(long n){
    if(n==2||n==3||n==5||n==7)return true;
    else if(n%2==0||n%3==0||n%5==0||n%7==0)return false;
    else{
        for(long i=11;i<n;i+=2){
            if(n%i==0)return false;
        }
        return true;
    }
}

/**
 * Calculates primes using the atandard Sieve of Eratosthenes.
 * Uses 2,3,5,7 wheel factorization for elimination (hardcoded for performance reasons)
 * @param MAX : argument x for pi(x)
 * Will delegate to <code>primeCount(long)</code> for MAX<LOW_LIM and to <code>bitPrimeSieve(long)</code>
 * for MAX>HIGH_LIM, for performance reasons.
 */
public static long primeSieve(long MAX){
    if(MAX<=1)return 0;
    else if(LOW_LIM>0&&MAX<LOW_LIM){return primeCount(MAX);}
    else if(HIGH_LIM>0&&MAX>HIGH_LIM){return bitPrimeSieve(MAX);}
    int n=(int)MAX;
    int sn=(int)Math.sqrt(n),ctr=2;
    if(sn%2==0)--sn;
    boolean[]ps=new boolean[n+1];
    for(int i=2;i<=n;++i){
        if(i==2||i==3||i==5||i==7)ps[i]=true;
        else if(i%2!=0&&i%3!=0&&i%5!=0&&i%7!=0)ps[i]=true;
        else ++ctr;
    }
    for(int i=(n>10)?11:3;i<=sn;i+=2){
        if(ps[i]){
            for(int j=i*i;j<=n;j+=i){
                if(ps[j]){ ps[j]=false;++ctr;}
            }
        }
    }
    return (n+1-ctr);
}
/**
 * Calculates primes using bitmasked Sieve of Eratosthenes.
 * @param MAX : argument x for pi(x)
 */
public static long bitPrimeSieve(long MAX) {
    long SQRT_MAX = (long) Math.sqrt(MAX);
    if(SQRT_MAX%2==0)--SQRT_MAX;
    int MEMORY_SIZE = (int) ((MAX+1) >> 4);
    byte[] array = new byte[MEMORY_SIZE];
    for (long i = 3; i <= SQRT_MAX; i += 2) {
        if ((array[(int) (i >> 4)] & (byte) (1 << ((i >> 1) & 7))) == 0) {
            for(long j=i*i;j<=MAX;j+=i<<1) {
                if((array[(int) (j >> 4)] & (byte) (1 << ((j >> 1) & 7))) == 0){
                    array[(int) (j >> 4)] |= (byte) (1 << ((j >> 1) & 7));
                }
            }
        }
    }
    long pi = 1;
    for (long i = 3; i <= MAX; i += 2) {
        if ((array[(int) (i >> 4)] & (byte) (1 << ((i >> 1) & 7))) == 0) {
            ++pi;
        }
    }
    return pi;
}
/**
 * Private testing and timer function
 * @param MAX : input to be passed on to <code>primeSieve(long)</code>
 */
private static long sieveTest(long MAX){
    long start=System.nanoTime();
    long ps=primeSieve(MAX);
    long end=System.nanoTime();
    System.out.format(TEST_FORMAT,MAX,ps,((end-start)/1E9));
    return end-start;
}
/**
 * Main method: accepts user input and shows total execution time taken
 * @param args : The command-line arguments
 */
public static void main(String[]args){
    double total_time=0;
    java.util.Scanner sc=new java.util.Scanner(System.in);
    java.util.ArrayList<Long> numbers=new java.util.ArrayList<>();
    System.out.format(PROMPT+WARNING);
    String line=sc.nextLine();
    while(!line.equals(START_CODE)/*sc.hasNextLine()&&Character.isDigit(line.charAt(0))*/){
        numbers.add(Long.valueOf(line));
        line=sc.nextLine();
    }
    System.out.format(WAIT);
    for(long num:numbers){
        total_time+=sieveTest(num);
    }
    System.out.format(TOTAL_OUTPUT_FORMAT,total_time/1e9);
}
}

```

Follows in the great PPCG tradition of self-documenting code (although not in the literal sense :p).

This is to prove the point that Java can be fast enough to be competitive with other VM languages when using similar algorithms.

# Run information

Run it as you would have @CoolestVeto's answer, but mine doesn't need command-line arguments, it can get them from STDIN.

Tweak the `NUM_THREADS` constant to set it to 2x your native core count for maximum performance (as I observed - In my case I have 8 virtual cores so it is set to 16, the OP might want 12 for his hexa-core processor).

When I ran these tests I used JDK 1.7.0.45 with BlueJ 3.1.6 (IntelliJ was updating) on Windows 10 Enterpise x64 on a ASUS K55VM laptop (Core i7 3610QM, 8GB RAM). Google Chrome 49.0 64-bit with 1 tab (PPCG) open and QBittorrent downloading 1 file were running in the background, 60% RAM usage at start of run.

Basically,

```
javac PrimeCounter.java
java PrimeCounter

```

The program will walk you through the rest.

Timing is done by Java's inbuilt `System.nanoTime()`.

# Algorithm details:

Has 3 variants for different use cases - a naive version like @CoolestVeto's (but multithreaded) for inputs below 2^15, and a bitmasked sieve of Eratosthenes with odd-elimination for inputs above 2^28, and a normal sieve of Eratosthenes with a 2/3/5/7 wheel factorization for pre-elimination of multiples.

I use the bitmasked sieve to avoid special JVM arguments for the largest test cases. If that can be done, the overhead for the calculation of the count in the bitmasked version can be eliminated.

Here's the output:

```
Enter numbers to compute pi(x) for (Type "=" to start):
Probably won't work with values close to or more than 2^31
41500
24850000
40550000
99820000
660000000
1240000000
1337000000
1907000000
=
Calculating, please wait...
Input = 41500 , Output = 4339 , calculated in 0.002712 seconds
Input = 24850000 , Output = 1557132 , calculated in 0.304792 seconds
Input = 40550000 , Output = 2465109 , calculated in 0.523999 seconds
Input = 99820000 , Output = 5751639 , calculated in 1.326542 seconds
Input = 660000000 , Output = 34286170 , calculated in 4.750049 seconds
Input = 1240000000 , Output = 62366021 , calculated in 9.160406 seconds
Input = 1337000000 , Output = 66990613 , calculated in 9.989093 seconds
Input = 1907000000 , Output = 93875448 , calculated in 14.832107 seconds
Total time for all inputs is 40.889700 seconds

```

# Answer
> 2 votes
# Python 3.8

I wrote this janky code a long time ago based on some blogpost about Meissel-Lehmer I read. I'm not even sure how it works any more. One day I'll get around to cleaning it up and optimizing it.

Unofficial timing for 1907000000 case is 0.98 sec.

```
def memoize(obj):
    """Decorator that memoizes a function's calls. Credit: Python wiki"""
    # ignores **kwargs
    from functools import wraps
    cache = obj.cache = {}

    @wraps(obj)
    def memoizer(*args, **kwargs):
        if args not in cache:
            cache[args] = obj(*args, **kwargs)
        return cache[args]

    return memoizer

def prime_count_sieve(n, primes):
    from bisect import bisect
    return bisect(primes, n)

_prime_count_p = None
_prime_count_limit = 10**4

@memoize
def _phi(x, a):
    if a == 1:
        return (x + 1) // 2
    return _phi(x, a-1) - _phi(x // _prime_count_p[a], a-1)

@memoize
def _pi(n):
    if n < _prime_count_limit:
        return prime_count_sieve(n, _prime_count_p[1:])

    z = int((n + 0.5)**0.5)
    a = _pi(int(z**0.5 + 0.5))
    b = _pi(z)
    c = _pi(int(n**(1/3) + 0.5))
    s = _phi(n, a) + (b+a-2)*(b-a+1)//2

    for i in range(a+1, b+1):
        w = n / _prime_count_p[i]
        lim = _pi(int(w**0.5))
        s -= _pi(int(w))
        if i <= c:
            for j in range(i, lim+1):
                s += -_pi(int(w / _prime_count_p[j])) + j - 1
    return s

def prime_count(n):
    # a-th prime for small a (1-indexed)
    global _prime_count_p
    sieve_max = int(n**0.5)+1  # can be optimized

    return _pi(n)

```

# Answer
> 1 votes
# C++, 9.3221s (29 Feb 2016)

```
#include <cstdint>
#include <vector>
#include <iostream>
#include <limits>
#include <cmath>
#include <array>
// uses posix ffsll
#include <string.h>
#include <algorithm>

constexpr uint64_t wheel_width = 2;
constexpr uint64_t buf_size = 1<<(10+6);
constexpr uint64_t dtype_width = 6;
constexpr uint64_t dtype_mask = 63;
constexpr uint64_t buf_len = ((buf_size*wheel_width)>>dtype_width);

typedef std::vector<uint64_t> buf_type;

void mark_composite(buf_type& buf, uint64_t prime,
                    std::array<uint64_t, 2>& poff,
                    uint64_t seg_start, uint64_t max_j)
{
  const auto p = 2*prime;
  for(uint64_t k = 0; k < wheel_width; ++k)
  {
    for(uint64_t j = 2*poff[k]+(k==0); j < max_j; j += p)
    {
      buf[(j-seg_start)>>dtype_width] |= 1ULL << (j & dtype_mask);
      poff[k] += prime;
    }
  }
}

uint64_t num_primes(uint64_t n)
{
  uint64_t res = (n >= 2) + (n >= 3);
  if(n >= 5)
  {
    buf_type buf(buf_len);
    // compute and store primes < sqrt(n)
    const uint64_t store_max = ceil(sqrt(n));

    // only primes >= 5
    std::vector<uint64_t> primes; // 5,7,11
    std::vector<std::array<uint64_t, 2> > poffs;// {{3,0},{0,5},{8,1}};
    primes.reserve(ceil(1.25506*store_max/log(store_max)));
    poffs.reserve(ceil(1.25506*store_max/log(store_max)));
    uint64_t seg_start = 0;
    uint64_t seg_min = 5;
    constexpr uint64_t seg_len = 6*buf_size;///wheel_width;
    constexpr uint64_t limit_i_max = 0xfffffffe00000001ULL;
    const uint64_t num_segs = 1+(n-seg_min)/seg_len;
    const uint64_t nj = (n-seg_min)/3+1;
    for(uint64_t seg = 0; seg < num_segs; ++seg)
    {
      std::fill(buf.begin(), buf.end(), 0);
      // mark off small primes
      const uint64_t limit_i = std::min<uint64_t>((((seg_len+seg_min) >= limit_i_max) ?
                                                   std::numeric_limits<uint32_t>::max() :
                                                   ceil(sqrt(seg_len+seg_min))),
                                                  store_max);
      uint64_t max_j = std::min(seg_start+(buf_len<<dtype_width), nj);
      for(uint64_t i = 0; i < primes.size() && primes[i] <= limit_i; ++i)
      {
        mark_composite(buf, primes[i], poffs[i], seg_start, max_j);
      }
      // sieve
      uint64_t val;
      const uint64_t stop = std::min(seg_min+seg_len, n);
      for(uint64_t i = ffsll(~(buf[0]))-((~buf[0]) != 0)+64*((~buf[0]) == 0);
            (val = 6ULL*(i>>1)+seg_min+2ULL*(i&1ULL)) < stop;)
      {
        if(!(buf[i>>dtype_width] & (1ULL << (i & dtype_mask))))
        {
          if(val <= store_max)
          {
            // add prime and poffs
            primes.push_back(val);
            poffs.emplace_back();
            poffs.back()[0] = (val*val-1)/6-1;
            if(i&1)
            {
              // 6n+1 prime
              poffs.back()[1] = (val*val+4*val-5)/6;
            }
            else
            {
              // 6n+5 prime
              poffs.back()[1] = (val*val+2*val-5)/6;
            }
            // mark-off multiples
            mark_composite(buf, val, poffs.back(), seg_start, max_j);
          }
          ++res;
          ++i;
        }
        else
        {
          uint64_t mask = buf[i>>dtype_width]>>(i&dtype_mask);
          const int64_t inc = ffsll(~mask)-((~mask) != 0)+64*((~mask) == 0);
          i += inc;
        }
      }
      seg_min += seg_len;
      seg_start += buf_size*wheel_width;
    }
  }
  return res;
}

int main(int argc, char** argv)
{
  if(argc <= 1)
  {
    std::cout << "usage: " << argv[0] << " n\n";
    return -1;
  }
  std::cout << num_primes(std::stoll(argv[1])) << '\n';
}

```

Uses a segmented sieve of Eratosthenes with a wheel factorization of 6 to skip all multiples of 2/3. Makes use of the POSIX `ffsll` to skip consecutive composite values.

Could potentially be sped up by making the segmented sieve work in parallel.

To compile:

```
g++ -std=c++11 -o sieve -O3 -march=native sieve.cpp

```

## unofficial timings

Timed with an Intel i5-6600k on Ubuntu 15.10, the 1907000000 case took `2.363s`.

```
41500
4339

real    0m0.001s
user    0m0.000s
sys     0m0.000s

24850000
1557132

real    0m0.036s
user    0m0.032s
sys     0m0.000s

40550000
2465109

real    0m0.056s
user    0m0.052s
sys     0m0.000s

99820000
5751639

real    0m0.149s
user    0m0.144s
sys     0m0.000s

660000000
34286170

real    0m0.795s
user    0m0.788s
sys     0m0.000s

1240000000
62366021

real    0m1.468s
user    0m1.464s
sys     0m0.000s

1337000000
66990613

real    0m1.583s
user    0m1.576s
sys     0m0.004s

1907000000
93875448

real    0m2.363s
user    0m2.356s
sys     0m0.000s

```

**Official Times**

```
real    0m9.415s
user    0m9.414s
sys 0m0.014s

real    0m9.315s
user    0m9.315s
sys 0m0.013s

real    0m9.307s
user    0m9.309s
sys 0m0.012s

real    0m9.333s
user    0m9.330s
sys 0m0.017s

real    0m9.288s
user    0m9.289s
sys 0m0.012s

real    0m9.319s
user    0m9.318s
sys 0m0.015s

real    0m9.285s
user    0m9.284s
sys 0m0.015s

real    0m9.342s
user    0m9.342s
sys 0m0.014s

real    0m9.305s
user    0m9.305s
sys 0m0.014s

real    0m9.312s
user    0m9.313s
sys 0m0.012s

```

# Answer
> 1 votes
# Scala

Port of @orlp's Java answer in Scala.

So slow.

Try it online!

```
object E extends App {
  println(numPrime(args(0).toInt))

  def numPrime(max: Int): Int = {
    (0 until max).count(isPrime)
  }

  def isPrime(n: Int): Boolean = {
    if(n < 2) false
    else if(n == 2 || n == 3) true
    else if(n%2 == 0 || n%3 == 0) false
    else {
      val sqrtN = math.sqrt(n).toInt + 1
      !(6 to sqrtN by 6).exists(i => n%(i-1) == 0 || n%(i+1) == 0)
    }
  }
}

```

---
Tags: math, number, number-theory, primes, fastest-code
---