Algorithm Search⌘K

Proofs: Lucy_Hedgehog prime counting

These are the human proofs of Lucy_Hedgehog prime counting, at full length.

The Lucy_Hedgehog method returns pi(x) full

This proof shows: correctness.

For m≥2m \ge 2 let lpf(m)\mathrm{lpf}(m) be the least prime factor of mm; a composite mm satisfies lpf(m)2≤m\mathrm{lpf}(m)^2 \le m, because m=lpf(m)⋅km = \mathrm{lpf}(m) \cdot k with k≥2k \ge 2, and every prime factor of kk is at least lpf(m)\mathrm{lpf}(m). For q≥1q \ge 1 and v≥0v \ge 0 let Sq(v)=#{2≤n≤v:n prime or lpf(n)>q}S_q(v) = \#\{ 2 \le n \le v : n \text{ prime or } \mathrm{lpf}(n) > q \}.

If x<2x < 2, line L1 returns 0, which is π(x)\pi(x). Assume x≥2x \ge 2, so r=⌊x⌋≥1r = \lfloor \sqrt x \rfloor \ge 1, and let V={⌊x/k⌋:k≥1}V = \{\lfloor x/k \rfloor : k \ge 1\}.

Facts about VV. (a) For v∈Vv \in V and an integer p≥1p \ge 1, ⌊v/p⌋∈V\lfloor v/p \rfloor \in V or ⌊v/p⌋=0\lfloor v/p \rfloor = 0: if v=⌊x/k⌋v = \lfloor x/k \rfloor, then ⌊v/p⌋=⌊x/(kp)⌋\lfloor v/p \rfloor = \lfloor x/(kp) \rfloor, since writing x=kpq+sx = kpq + s with 0≤s<kp0 \le s < kp gives ⌊x/k⌋=pq+⌊s/k⌋\lfloor x/k \rfloor = pq + \lfloor s/k \rfloor with ⌊s/k⌋<p\lfloor s/k \rfloor < p. (b) Every integer 1≤v≤r1 \le v \le r is in VV. Let k=⌊x/v⌋k = \lfloor x/v \rfloor; then k≥x/v−1k \ge x/v - 1 and, since v2≤xv^2 \le x, k≥vk \ge v. As k≤x/vk \le x/v, ⌊x/k⌋≥v\lfloor x/k \rfloor \ge v. If ⌊x/k⌋≥v+1\lfloor x/k \rfloor \ge v + 1, then k(v+1)≤xk(v+1) \le x, so x/v−1<k≤x/(v+1)x/v - 1 < k \le x/(v+1), which gives x<v(v+1)x < v(v+1); but k≥vk \ge v and k(v+1)≤xk(v + 1) \le x give v(v+1)≤xv(v+1) \le x, a contradiction. So ⌊x/k⌋=v\lfloor x/k \rfloor = v.

Invariant. For p=2,…,r+1p = 2, \ldots, r + 1: at the start of round pp of line L4 (or after the loop, for p=r+1p = r + 1), S[v]=Sp−1(v)S[v] = S_{p-1}(v) for all v∈Vv \in V.

Base. For p=2p = 2, line L3 sets S[v]=v−1=#{2≤n≤v}=S1(v)S[v] = v - 1 = \#\{2 \le n \le v\} = S_1(v), since every n≥2n \ge 2 has lpf(n)≥2>1\mathrm{lpf}(n) \ge 2 > 1.

Step. Assume the invariant at the start of round pp, with 2≤p≤r2 \le p \le r. By fact (b), pp and p−1p - 1 lie in VV.

First, Sp−1(p)−Sp−1(p−1)S_{p-1}(p) - S_{p-1}(p-1) is 1 if pp counts in Sp−1(p)S_{p-1}(p) and 0 otherwise, that is, 1 if and only if pp is prime or lpf(p)>p−1\mathrm{lpf}(p) > p - 1. As lpf(p)≤p\mathrm{lpf}(p) \le p, lpf(p)>p−1\mathrm{lpf}(p) > p - 1 means lpf(p)=p\mathrm{lpf}(p) = p, that is, pp is prime. So the test of line L5 holds exactly when pp is composite.

Case pp composite. No nn has lpf(n)=p\mathrm{lpf}(n) = p, since lpf(n)\mathrm{lpf}(n) is prime. So lpf(n)>p−1\mathrm{lpf}(n) > p - 1 if and only if lpf(n)>p\mathrm{lpf}(n) > p, hence Sp=Sp−1S_p = S_{p-1}, and line L5 leaves SS unchanged, as required.

Case pp prime. Comparing the definitions, Sp−1(v)−Sp(v)S_{p-1}(v) - S_p(v) is the number of 2≤n≤v2 \le n \le v that are not prime and have lpf(n)=p\mathrm{lpf}(n) = p; call this Cp(v)C_p(v). If v<p2v < p^2, then Cp(v)=0C_p(v) = 0, because a composite nn with lpf(n)=p\mathrm{lpf}(n) = p has n≥p2n \ge p^2. Let v≥p2v \ge p^2 and w=⌊v/p⌋≥pw = \lfloor v/p \rfloor \ge p. The map n↦k=n/pn \mapsto k = n/p is a bijection from the composites n≤vn \le v with lpf(n)=p\mathrm{lpf}(n) = p to the integers 2≤k≤w2 \le k \le w with lpf(k)≥p\mathrm{lpf}(k) \ge p: if n=pkn = pk is such a composite, then k≥2k \ge 2, k≤v/pk \le v/p, and every prime factor of kk divides nn, hence is at least pp; conversely, if 2≤k≤w2 \le k \le w has lpf(k)≥p\mathrm{lpf}(k) \ge p, then n=pk≤vn = pk \le v is composite with lpf(n)=p\mathrm{lpf}(n) = p. The integers 2≤k≤w2 \le k \le w that count in Sp−1(w)S_{p-1}(w) are those that are prime or have lpf(k)≥p\mathrm{lpf}(k) \ge p; the ones among them with lpf(k)<p\mathrm{lpf}(k) < p are exactly the primes below pp, and all π(p−1)\pi(p - 1) of them are at most p−1<wp - 1 < w. Hence Cp(v)=Sp−1(w)−π(p−1)C_p(v) = S_{p-1}(w) - \pi(p - 1). Finally Sp−1(p−1)=π(p−1)S_{p-1}(p - 1) = \pi(p - 1), because every 2≤n≤p−12 \le n \le p - 1 has lpf(n)≤n≤p−1\mathrm{lpf}(n) \le n \le p - 1, so only the primes count. By the invariant, line L6 sets c=Sp−1(p−1)=π(p−1)c = S_{p-1}(p - 1) = \pi(p - 1).

Line L7 visits the v∈Vv \in V with v≥p2v \ge p^2 in decreasing order. When it updates vv, it reads S[w]S[w] with w=⌊v/p⌋∈Vw = \lfloor v/p \rfloor \in V by fact (a) (w≥p≥1w \ge p \ge 1), and w<vw < v; every value updated earlier in this round is larger than vv, so S[w]S[w] still holds Sp−1(w)S_{p-1}(w). Also p−1<p2p - 1 < p^2, so S[p−1]S[p - 1] is not changed in this round, and cc is correct throughout. So line L8 sets S[v]=Sp−1(v)−(Sp−1(w)−π(p−1))=Sp−1(v)−Cp(v)=Sp(v)S[v] = S_{p-1}(v) - (S_{p-1}(w) - \pi(p-1)) = S_{p-1}(v) - C_p(v) = S_p(v). Each vv is updated once, from its old value Sp−1(v)S_{p-1}(v). The values v<p2v < p^2 are not touched and keep Sp−1(v)=Sp(v)S_{p-1}(v) = S_p(v). So the invariant holds at the start of round p+1p + 1.

Conclusion. After the loop, S[x]=Sr(x)S[x] = S_r(x) (and x∈Vx \in V with k=1k = 1). Every composite n≤xn \le x has lpf(n)≤n≤x\mathrm{lpf}(n) \le \sqrt n \le \sqrt x, hence lpf(n)≤r\mathrm{lpf}(n) \le r, so it does not count in Sr(x)S_r(x), while every prime n≤xn \le x does. So line L9 returns Sr(x)=π(x)S_r(x) = \pi(x).

The two arrays. The implementation stores S[v]S[v] at small[v] for v≤rv \le r and at large[k] for v=⌊x/k⌋v = \lfloor x/k \rfloor, 1≤k≤r1 \le k \le r. Every v∈Vv \in V with v>rv > r has such a kk, namely k=⌊x/v⌋k = \lfloor x/v \rfloor: from v=⌊x/j⌋v = \lfloor x/j \rfloor we get j≤x/vj \le x/v, so j≤kj \le k and ⌊x/k⌋≤v\lfloor x/k \rfloor \le v, while k≤x/vk \le x/v gives ⌊x/k⌋≥v\lfloor x/k \rfloor \ge v; and k≤x/v<x/x=xk \le x/v < x/\sqrt x = \sqrt x, so k≤rk \le r. The loop over large for k=1,2,…k = 1, 2, \ldots followed by the loop over small from rr down is a pass in decreasing order of vv, the cell read for ⌊x/(kp)⌋\lfloor x/(kp) \rfloor is large[kp] if kp≤rkp \le r and small[x // (kp)] otherwise, and in the latter case ⌊x/(kp)⌋≤r\lfloor x/(kp) \rfloor \le r holds, because kp≥r+1>xkp \ge r + 1 > \sqrt x. A value stored in both arrays receives the same update in both, from the same old values, so the two copies stay equal. ■\blacksquare

Back to Lucy_Hedgehog prime counting