| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include |
|
2
|
|
|
|
|
|
|
#include |
|
3
|
|
|
|
|
|
|
#include |
|
4
|
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
#include "ptypes.h" |
|
6
|
|
|
|
|
|
|
#include "goldbach.h" |
|
7
|
|
|
|
|
|
|
#define FUNC_is_prime_in_sieve 1 |
|
8
|
|
|
|
|
|
|
#include "sieve.h" |
|
9
|
|
|
|
|
|
|
#include "cache.h" |
|
10
|
|
|
|
|
|
|
#include "primality.h" |
|
11
|
|
|
|
|
|
|
#include "util.h" |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
/* TODO: Consider adding Waring-Goldbach(n,k,t) */ |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
|
|
16
|
41
|
|
|
|
|
|
UV minimal_goldbach_pair(UV n) |
|
17
|
|
|
|
|
|
|
{ |
|
18
|
|
|
|
|
|
|
UV p; |
|
19
|
41
|
100
|
|
|
|
|
if (n < 4) return 0; |
|
20
|
37
|
100
|
|
|
|
|
if (n & 1 || n == 4) |
|
|
|
100
|
|
|
|
|
|
|
21
|
15
|
100
|
|
|
|
|
return (is_prime(n-2)) ? 2 : 0; |
|
22
|
|
|
|
|
|
|
/* Maybe this could be faster using a sieve. Max p < 4*10^18 is 9781 */ |
|
23
|
1720
|
50
|
|
|
|
|
for (p=3; p <= n/2; p = next_prime(p)) |
|
24
|
1720
|
100
|
|
|
|
|
if (is_prime(n-p)) |
|
25
|
22
|
|
|
|
|
|
return p; |
|
26
|
0
|
|
|
|
|
|
return 0; |
|
27
|
|
|
|
|
|
|
} |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
#if 0 |
|
30
|
|
|
|
|
|
|
/* Some ways for finding Goldbach pairs */ |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
/* 1. Simple */ |
|
33
|
|
|
|
|
|
|
START_DO_FOR_EACH_PRIME(3,n/2) { |
|
34
|
|
|
|
|
|
|
if (is_prob_prime(n-p)) |
|
35
|
|
|
|
|
|
|
L[s++] = p; |
|
36
|
|
|
|
|
|
|
} END_DO_FOR_EACH_PRIME |
|
37
|
|
|
|
|
|
|
Renew(L, s, UV); *size=s; return L; |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
/* 2. Get a full list then walk from the edges. Not bad for small sizes. */ |
|
40
|
|
|
|
|
|
|
if (n >= 22 && n < 4294967295U) { |
|
41
|
|
|
|
|
|
|
uint32_t *pr; |
|
42
|
|
|
|
|
|
|
UV nprimes = range_prime_sieve_32(&pr, n, 0); /* pr[0]=2, pr[1]=3, */ |
|
43
|
|
|
|
|
|
|
UV i = 4, j = nprimes-1; |
|
44
|
|
|
|
|
|
|
while (i <= j) { |
|
45
|
|
|
|
|
|
|
UV sum = pr[i] + pr[j]; |
|
46
|
|
|
|
|
|
|
if (sum > n) { |
|
47
|
|
|
|
|
|
|
j--; |
|
48
|
|
|
|
|
|
|
} else { |
|
49
|
|
|
|
|
|
|
if (sum == n) |
|
50
|
|
|
|
|
|
|
L[s++] = pr[i]; |
|
51
|
|
|
|
|
|
|
i++; |
|
52
|
|
|
|
|
|
|
} |
|
53
|
|
|
|
|
|
|
} |
|
54
|
|
|
|
|
|
|
Safefree(pr); |
|
55
|
|
|
|
|
|
|
} |
|
56
|
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
/* 3. Single sieve */ |
|
58
|
|
|
|
|
|
|
if (n >= 22) { |
|
59
|
|
|
|
|
|
|
unsigned char* segment; |
|
60
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
61
|
|
|
|
|
|
|
void* ctx = start_segment_primes(n/2, n-11, &segment); |
|
62
|
|
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
63
|
|
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) |
|
64
|
|
|
|
|
|
|
UV q = n-p; |
|
65
|
|
|
|
|
|
|
if (is_prob_prime(q)) |
|
66
|
|
|
|
|
|
|
L[s++] = q; |
|
67
|
|
|
|
|
|
|
END_DO_FOR_EACH_SIEVE_PRIME |
|
68
|
|
|
|
|
|
|
} |
|
69
|
|
|
|
|
|
|
end_segment_primes(ctx); |
|
70
|
|
|
|
|
|
|
sort_uv_array(L, s); |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
/* The double sieve, low as inner, comes out fastest. */ |
|
74
|
|
|
|
|
|
|
#endif |
|
75
|
|
|
|
|
|
|
|
|
76
|
38
|
|
|
|
|
|
static UV sieve_pairs(UV* L, UV n) { |
|
77
|
38
|
|
|
|
|
|
size_t s = 0; |
|
78
|
38
|
100
|
|
|
|
|
if (n >= 22) { |
|
79
|
|
|
|
|
|
|
unsigned char* segment; |
|
80
|
|
|
|
|
|
|
UV seg_base, seg_low, seg_high; |
|
81
|
22
|
|
|
|
|
|
void* ctx = start_segment_primes(n/2, n-11, &segment); |
|
82
|
44
|
100
|
|
|
|
|
while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) { |
|
83
|
22
|
|
|
|
|
|
size_t qbeg = n-seg_high, qend = n-seg_low; |
|
84
|
22
|
|
|
|
|
|
UV qdbeg = qbeg/30, qdend = (qend+29)/30; |
|
85
|
|
|
|
|
|
|
unsigned char* lowsieve; |
|
86
|
22
|
|
|
|
|
|
New(0, lowsieve, qdend-qdbeg+1, unsigned char); |
|
87
|
22
|
|
|
|
|
|
sieve_segment(lowsieve, qdbeg, qdend); |
|
88
|
704
|
50
|
|
|
|
|
START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high ) |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
89
|
598
|
|
|
|
|
|
UV q = n-p; |
|
90
|
598
|
100
|
|
|
|
|
if (L) { |
|
91
|
299
|
100
|
|
|
|
|
if (is_prime_in_sieve(lowsieve, q-qdbeg*30)) |
|
92
|
74
|
|
|
|
|
|
L[s++] = q; |
|
93
|
|
|
|
|
|
|
} else { |
|
94
|
299
|
100
|
|
|
|
|
if (is_prime_in_sieve(lowsieve, q-qdbeg*30)) |
|
95
|
74
|
|
|
|
|
|
s++; |
|
96
|
|
|
|
|
|
|
} |
|
97
|
38
|
|
|
|
|
|
END_DO_FOR_EACH_SIEVE_PRIME |
|
98
|
22
|
|
|
|
|
|
Safefree(lowsieve); |
|
99
|
|
|
|
|
|
|
} |
|
100
|
22
|
|
|
|
|
|
end_segment_primes(ctx); |
|
101
|
22
|
100
|
|
|
|
|
if (L && s > 1) { /* Reverse the list */ |
|
|
|
100
|
|
|
|
|
|
|
102
|
6
|
|
|
|
|
|
size_t i = 0, j = s-1; |
|
103
|
40
|
100
|
|
|
|
|
while (i < j) { UV t=L[i]; L[i]=L[j]; L[j]=t; i++; j--; } |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
} |
|
106
|
38
|
|
|
|
|
|
return s; |
|
107
|
|
|
|
|
|
|
} |
|
108
|
|
|
|
|
|
|
|
|
109
|
38
|
|
|
|
|
|
UV* goldbach_pairs(size_t *size, UV n) |
|
110
|
|
|
|
|
|
|
{ |
|
111
|
|
|
|
|
|
|
UV *L; |
|
112
|
38
|
|
|
|
|
|
size_t s = 0; |
|
113
|
38
|
100
|
|
|
|
|
if (n < 4) return 0; |
|
114
|
34
|
100
|
|
|
|
|
if (n & 1 || n == 4) { |
|
|
|
100
|
|
|
|
|
|
|
115
|
15
|
100
|
|
|
|
|
if (!is_prime(n-2)) |
|
116
|
5
|
|
|
|
|
|
return 0; |
|
117
|
10
|
|
|
|
|
|
New(0, L, 1, UV); |
|
118
|
10
|
|
|
|
|
|
L[0] = 2; |
|
119
|
10
|
|
|
|
|
|
*size = 1; |
|
120
|
10
|
|
|
|
|
|
return L; |
|
121
|
|
|
|
|
|
|
} |
|
122
|
|
|
|
|
|
|
/* Overestimate */ |
|
123
|
19
|
50
|
|
|
|
|
New(0, L, max_nprimes(n/2) >> (n > 30030 ? 1 : 0), UV); |
|
124
|
|
|
|
|
|
|
|
|
125
|
19
|
50
|
|
|
|
|
if (n >= 6 && is_prime(n-3)) L[s++] = 3; |
|
|
|
100
|
|
|
|
|
|
|
126
|
19
|
100
|
|
|
|
|
if (n >= 10 && is_prime(n-5)) L[s++] = 5; |
|
|
|
100
|
|
|
|
|
|
|
127
|
19
|
100
|
|
|
|
|
if (n >= 14 && is_prime(n-7)) L[s++] = 7; |
|
|
|
100
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
|
|
129
|
19
|
|
|
|
|
|
s += sieve_pairs(L+s, n); |
|
130
|
|
|
|
|
|
|
|
|
131
|
19
|
50
|
|
|
|
|
Renew(L, s, UV); /* Possibly reduce storage */ |
|
132
|
19
|
|
|
|
|
|
*size = s; |
|
133
|
19
|
|
|
|
|
|
return L; |
|
134
|
|
|
|
|
|
|
} |
|
135
|
|
|
|
|
|
|
|
|
136
|
38
|
|
|
|
|
|
UV goldbach_pair_count(UV n) |
|
137
|
|
|
|
|
|
|
{ |
|
138
|
38
|
|
|
|
|
|
size_t s = 0; |
|
139
|
38
|
100
|
|
|
|
|
if (n < 4) return 0; |
|
140
|
34
|
100
|
|
|
|
|
if (n & 1 || n == 4) |
|
|
|
100
|
|
|
|
|
|
|
141
|
15
|
|
|
|
|
|
return (is_prime(n-2)) ? 1 : 0; |
|
142
|
|
|
|
|
|
|
|
|
143
|
19
|
50
|
|
|
|
|
if (n >= 6 && is_prime(n-3)) s++; |
|
|
|
100
|
|
|
|
|
|
|
144
|
19
|
100
|
|
|
|
|
if (n >= 10 && is_prime(n-5)) s++; |
|
|
|
100
|
|
|
|
|
|
|
145
|
19
|
100
|
|
|
|
|
if (n >= 14 && is_prime(n-7)) s++; |
|
|
|
100
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
|
|
147
|
19
|
|
|
|
|
|
s += sieve_pairs(0, n); |
|
148
|
|
|
|
|
|
|
|
|
149
|
19
|
|
|
|
|
|
return s; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
/* See https://arxiv.org/pdf/2601.16193 for ideas on upper,lower,approx. */ |