알고리즘에서 인용한 에라토스테네스의 체는 곱셈의 원리를 이용하는 특성상, 두 가지 법칙이 있습니다.
- 1과 알아보려는 마지막 수의 산술평균치, 즉 알아보려는 마지막 수의 제곱근보다 같거나 작은 소수의 배수를 거르고 나면, 그보다 큰 소수들은 범위 내에 배수가 자기뿐입니다. 즉 더 이상 알고리즘을 작동시키지 않아도 됩니다.
- 모든 소수는 자신의 제곱수인 배수부터 거를 수 있습니다. 즉 2승째보다 먼저 오는 배수는 자기보다 작은 소수의 배수를 거르는 시간에 전부 걸러진 뒤입니다.
이 법칙을 적용하면 이 알고리즘을 돌려야 하는 배열 범위를 줄이고, 반복문의 시행 횟수 자체도 줄일 수 있죠. 그러므로 개선된 방법을 공유합니다. 주석은 앞 부분에서 달라진 부분에만 달았으니 비교하며 읽으셨으면 합니다.
x = int(input("Key an integer to count the element numbers over than 1: "))
el_num = list(range(2, x+1))
for i in range(len(el_num)):
if(el_num[i] == 0):
continue
if(el_num[i] ** 2 > x):
# 거르기에 쓰는 소수의 제곱이 알아보려는 범위의 수보다 크면, 더 이상 반복문을 돌리지 않아도 됩니다.
break //거르기 종료
for j in range(((i + 2) ** 2 - 2), len(el_num)):
# 걸러서 0으로 만들기 시작할 제곱수의 좌표를 구하는 점화식 추가.
if(el_num[j] == 0):
continue
if(el_num[j] % el_num[i] == 0):
el_num[j] = 0
while 0 in el_num:
el_num.remove(0)
print(el_num)
해당 법칙은 소수 탐지 알고리즘을 찾아보다 발견한 이 페이지(링크)에서 깨달았습니다.
또한 위키백과의 ‘에라토스테네스의 체’ 항목(링크)에서도 최적화된 여러 프로그래밍 언어로의 알고리즘 예시가 소개되어 있으니 해당 문서를 참고하시는 것도 도움이 될 듯합니다.
역시 제가 쓴 코드를 Atom으로 구현한 갈무리 화면으로 소개하면 이렇습니다.