소수를 구하고 n보다 크고 2n보다 같거나 작은 범위를 추려 개수를 출력한다.
소수 판별 함수:
에라토스테네스의 체 방식을 이용하여 1을 제외한 가장 작은 수의 배수를 지워나갈 것이다.
array 생성
:
1부터 N까지의 배열을 만든다. 소수가 아닌 수를 지워나가기 위해 초기값은 모두 True로 설정한다. 숫자와 인덱스를 일치시키기 위해 범위를 n+1로 늘렸다.
반복문
:
array[i]에는 i라는 수가 소수인지 아닌 지에 대한 boolean 값이 저장되어 있다. 이 인덱스를 반복문으로 돌리며 소수 여부를 판단할 것이다. 이 때 반복하는 범위가 2 ~ int(N**0.5)+1
인데 의미는 아래와 같다.
1은 소수가 아니므로 1을 제외한 가장 작은 수인 2부터 시작한다.
N**0.5
는 N의 0.5승, 제곱근을 의미한다. 범위를 제곱근까지 제한하는 이유는 1부터 N까지의 수를 나열했을 때 N의 제곱근을 기준으로 대칭되는 수들이 N의 약수(약수의 법칙) 가 되기 때문이다. N의 제곱근보다 작은 수로도 배수들이 모두 제거되기 때문에 N의 제곱근보다 큰 수를 기준으로 반복문을 돌려도 제거할 수가 남아있지 않아 의미가 없다.
if array[i] == True
:
해당 값이 True라는 의미는 아직 제거되지 않았다는 것이므로 종속된 코드를 실행한다. 이미 제거된 수라면 다음 i로 넘어간다.
while i*j ≤=N
:
i라는 수와 j (배열에 잔존하는 수 중 가장 작은 수)의 곱이 N을 초과할 때까지 반복한다. 반복문에 j를 1씩 증가시키는 코드가 있으므로 i*j의 곱이 N을 넘지 않는 범위 안에서 j는 계속 증가하여 j의 배수를 모두 False로 바꾼다.
max(test_case)
)의 범위(2*n = 2*max(test_case)
)를 기준으로 하여 계산한다. 그렇게 해야 다른 테스트 케이스에도 활용할 수 있다.
test_case = []
while True:
n = int(input())
if n == 0:
break
test_case.append(n)
def is_prime(N):
array = [True for i in range(N+1)]
for i in range(2,int(N**0.5)+1):
if array[i] == True:
j = 2
while i*j <= N:
array[i*j] = False
j+=1
return array
prime_list = is_prime(2*max(test_case))
for n in test_case:
num_of_prime = 0
for i in range(n+1,2*n+1): #입력값 범위 내에서만 출력되도록 지정
if prime_list[i] and i!=1: #1은 소수가 아니므로 제외
num_of_prime +=1
print(num_of_prime)