-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgiwps.py
81 lines (62 loc) · 2.57 KB
/
giwps.py
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
70
71
72
73
74
75
76
77
78
79
80
81
import argparse
import itertools
import concurrent.futures
from math import factorial, log
import multiprocessing
from pandas import DataFrame
import re
import timeit
class WilsonPrimeSearch:
def __init__(self, search_floor, search_ceiling):
self.search_floor = search_floor
self.search_ceiling = search_ceiling
def erat2(self):
D = {}
yield 2
for q in itertools.islice(itertools.count(3), 0, None, 2):
p = D.pop(q, None)
if p is None:
D[q*q] = q
yield q
else:
x = p + q
while x in D or not (x&1):
x += p
D[x] = p
def get_primes_erat(self, n):
return list(itertools.takewhile(lambda p: p<n, self.erat2()))
def wilson_prime_remainder(self, x):
return x, (factorial(x-1)+1) % (x**2)
def run_search(self):
print('search zone: {:.2e} -> {:.2e}'.format(self.search_floor, self.search_ceiling))
print('conjectured estimate # of Wilson Primes: {}'.format(self.conjectured_num_wp))
print('searching in parallel on {} cores'.format(multiprocessing.cpu_count()))
print('\n')
print('primes | remainders')
df = DataFrame()
with concurrent.futures.ProcessPoolExecutor() as executor:
search_zone = self.get_primes_erat(self.search_ceiling)
search_zone = [x for x in search_zone if x > self.search_floor]
results = executor.map(self.wilson_prime_remainder, search_zone)
for result in results:
df = df.append([result])
print(result)
fname = 'results_{:.2e}_{:.2e}'.format(self.search_floor, self.search_ceiling)
fname = re.sub(r'[^\w]', '', fname)
df = df.rename(columns={0: 'primes', 1: 'remainders'})
df.to_csv(f'/data_output/{fname}.csv', index=False)
@property
def conjectured_num_wp(self):
return log(log(self.search_ceiling)/log(self.search_floor))
parser = argparse.ArgumentParser(description='search for wilson primes within a given search zone')
parser.add_argument('-floor', type=int, help='start of search zone')
parser.add_argument('-ceiling', type=int, help='end of search zone')
args = parser.parse_args()
def main(search_floor, search_ceiling):
start = timeit.default_timer()
wps = WilsonPrimeSearch(search_floor, search_ceiling+1)
wps.run_search()
stop = timeit.default_timer()
print(f'search runtime: {stop-start}')
if __name__ == '__main__':
main(args.floor, args.ceiling)