다시금 소수를 세자. Python으로 엔리코 푸치 신부님을 뛰어넘는 거야.

노들 영산

다시금 소수를 세자. Python으로 엔리코 푸치 신부님을 뛰어넘는 거야.

Spread the love

알고리즘에서 인용한 에라토스테네스의 체는 곱셈의 원리를 이용하는 특성상, 두 가지 법칙이 있습니다.

  • 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으로 구현한 갈무리 화면으로 소개하면 이렇습니다.