C언어에 비해 한참 느리긴 하지만 파이썬으로 작업하면 쉽고 편하게 할 수 있다.
소수 1천만개 구하는 데 1시간 이상 걸리니까 며칠 돌려 놓으면 몇 억개 구할 수 있지 않을까 희망해본다.
소수를 구해 리스트에 넣은 다음, 일정한 갯수(여기서는 1천만개)에 달하면 피클 파일로 저장한다.
매번 다른 파일명으로 차례로 저장하고, 무한 루프를 돈다. 뒤로 갈수록 시간이 점점 더 걸린다.
2억개 정도 마련하면 이 피클 파일들을 하나로 통합해서 관리하면 한결 수월할 것이다.
이 파이썬 코드를 실행하는 폴더 안에 data/라는 폴더를 미리 만들어두어야 한다. 생성되는 피클 파일이 여러 개인지라...
import math
import pickle
import os.path
def is_prime(num):
if num <= 1:
return False
if num == 2: return True
if num == 3: return True
if num % 2 == 0:
return False
root_val = int(math.sqrt(num)) + 1
for i in range(3, root_val, 2):
if num % i == 0:
return False
return True
def get_divisors2(from_num, until_num): # 양쪽 포함
num = from_num
primes = []
if num == 2:
print(num)
primes.append(num)
num += 1 # 3
if num == 3:
print(num)
primes.append(num)
num += 2
if num % 2 == 0: # 짝수라면, 홀수부터 시작
num += 1
u_num = until_num + 1
for x in range(num, u_num, 2): # 최소 5부터 시작
root_val = int(math.sqrt(x)) + 1
flag = True # 일단 True로 설정
for i in range(3, root_val, 2):
if x % i == 0: # 합성수라면
flag = False
break
if flag == True:
primes.append(x)
print(x)
return primes
def get_divisors(from_num, until_num): # 양쪽 포함
num = from_num
primes = []
if num == 2:
print(num)
primes.append(num)
num += 1 # 3
if num % 2 == 0: # 짝수라면, 홀수부터 시작
num += 1
u_num = until_num + 1
for x in range(num, u_num, 2): # x는 5부터 시작
if is_prime(x):
primes.append(x)
print(x)
return primes
def get_divisors3(from_num, howmany): # 양쪽 포함
num = from_num
primes = []
count = 0
if num == 2:
#print(num)
primes.append(num)
num += 1 # 3
count += 1
#if num == 3:
# print(num)
# primes.append(num)
# count += 1
if num % 2 == 0: # 짝수라면, 홀수부터 시작
num += 1 # 4라면 5
while count < howmany:
if is_prime(num):
primes.append(num)
count += 1
#print(num)
num += 2
return primes
#UINT_MAX = 4294967295
#ULONG_MAX = 18,446,744,073,709,551,615
#MAX_COUNT = 100000000 # 1억개
filename_base = "data/primes_"
MAX_COUNT = 10000000 # 천만개, 한번에 구할 소수 갯수
start_num = 1
count = 0 # 반복문 실행 회수: 생성되는 pkl 파일 갯수
while True:
primes = get_divisors3(start_num+1, MAX_COUNT)
count += 1
pkl_filename = filename_base + str(count) + ".pkl" # "primes_1.pkl"
if os.path.isfile(pkl_filename):
print(f"{pkl_filename}이 이미 있습니다.")
with open(pkl_filename, "wb") as pf:
pickle.dump(primes, pf)
length = len(primes)
print(f"{length} 개의 데이터를 피클로 저장했습니다.")
print(primes[:10]) # 첫 10개
print(primes[length-10:]) # 마지막 10개
start_num = primes[-1] # 마지막 소수 + 1에서 다시 검사 시작