-
Notifications
You must be signed in to change notification settings - Fork 39
Expand file tree
/
Copy pathprime_count_inclusion-exclusion_formula_faster.pl
More file actions
69 lines (51 loc) · 1.53 KB
/
Copy pathprime_count_inclusion-exclusion_formula_faster.pl
File metadata and controls
69 lines (51 loc) · 1.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#!/usr/bin/perl
# Author: Daniel Șuteu
# Date: 16 June 2026
# https://github.com/trizen
# A sublinear algorithm for counting the number of primes <= n, using the inclusion-exclusion principle.
# Inspired by the Veritasium video:
# https://youtube.com/watch?v=8HBDE-msUjw
# Formula:
# π(n) = n - Σ⌊n/p⌋ + Σ⌊n/(p·q)⌋ - ... + π(√n) - 1
use 5.036;
use ntheory 0.74 qw(:all);
sub almost_primes_from_factors_sum ($n, $primes, $k) {
my @factors = @$primes;
my $end = $#factors;
my $sum = 0;
sub ($m, $k, $i) {
if ($k == 1) {
for my $j ($i .. $end) {
my $q = $factors[$j];
last if $q > $m;
$sum += divint($m, $q);
}
return;
}
my $L = rootint($m, $k);
for my $j ($i .. $end) {
my $q = $factors[$j];
last if $q > $L;
__SUB__->(divint($m, $q), $k - 1, $j + 1);
}
}
->($n, $k, 0);
return $sum;
}
sub inclusion_exclusion_prime_count ($n) {
my $s = sqrtint($n);
my $primes = primes(2, $s);
my $count = $n + scalar(@$primes) - 1; # n + pi(sqrt(n)) - 1
for my $k (1 .. exp(LambertW(log($n))) + 1) {
$count += (-1)**$k * almost_primes_from_factors_sum($n, $primes, $k);
}
$count;
}
# Correctness check
for my $n (1 .. 1000) {
inclusion_exclusion_prime_count($n) == prime_count($n)
or die "error for n = $n";
}
for my $n (1 .. 7) {
say "pi(10^$n) = ", inclusion_exclusion_prime_count(10**$n);
}