카테고리 없음
(정수론/파이썬) 유클리드 아이디어를 이용해 새로운 소수 찾기
미친토끼
2021. 9. 11. 15:31
# '친절한 수론 길라잡이' 연습문제 12.1
# "소수가 무한히 많음을 증명하는 유클리드의 아이디어를 이용하여, 소수 목록 {5}로부터
# 새로운 소수들을 찾아보아라. 찾아낸 수들이 너무 커서 소인수분해하기 힘들 때까지 반복해 보자.
# (1000 보다 작은 수는 소인수분해를 할 수 있으리라 기대한다.)
def isPrime(num):
root_val = round(num ** 0.5) # 제곱근 값을 구한다
for i in range(2, root_val+1): # 제곱근값+1 까지만 약수를 조사해도 충분하다
if num % i == 0: # 중간에 나눠지면 소수가 아니다
return False
return True
# 소인수분해하여 그 목록을 돌려준다
# 가령 소인수분해 결과가 2^3*3^2*7 이라면,
# [2, 3, 7]을 돌려준다
def factorize_list(num):
divisor_primes = [] # 분해된 인수를 차곡차곡 저장하는 리스트
if isPrime(num): # 소수 판정
return divisor_primes
# 인수분해 루틴은 소수 판정 루틴과는 조금 다르게 접근할 필요가 있다.
i = 2
while True:
# i가 소수인지 검사해서 소수라면 num을 i로 나눈다
# i로 나눠서 나머지가 0이라면, 인수분해가 한번 된 것이다.
if isPrime(i) and num % i == 0:
divisor_primes.append(i) # 나누는 수를 저장 (가령, num이 12라면 i = 2)
num = num // i # 몫, 가령 24//2 = 12
#print(f"{i}, {num}")
# 12는 소수가 아니므로 반복문 계속. 소수가 나오면 그 소수를 저장하고 반복문 종료.
if isPrime(num):
divisor_primes.append(num)
break # return divisor_primes
i = 2 # 인수분해를 한번 했으므로 숫자를 2로 다시 나눠보기로 설정
else:
i += 1 # 인수분해가 되지 않으면 젯수(나누는 수)를 1증가
return sorted(set(divisor_primes)) # 중복 제거, 정렬하여 돌려주기
# 리스트에 든 숫자들을 모두 곱해서 결과를 돌려준다.
def multi(numbers):
gop = 1
for number in numbers:
gop *= number
return gop
primes = [2] # 찾아낸 소수들을 담는 리스트
while True:
new_num = multi(primes) + 1
if isPrime(new_num): # 소수라면 소수 목록에 추가
primes.append(new_num)
else: # 합성수라면 소인수분해한다.
divisors = factorize_list(new_num)
found = False
for d in divisors: # 예: [2, 3, 7]
if d not in primes: # 소수 목록에 없는 소수를 찾았다면, 목록에 추가
primes.append(d)
found = True # 찾았음을 표시
break
# 만일 해당 소수가 이미 목록에 있다면 인수분해된 소수 중 다음 소수를 for 문으로 시도한다.
if found == False: # 본인도 소수가 아니고 인수분해된 소수들이 이미 소수 목록에 들어 있다면 포기한다.
print("소수를 찾을 수 없습니다.")
exit(1)
print(primes)
'''
# 소수 목록 {5}에서 시작했을 때의 결과...
[5, 2]
[5, 2, 11]
[5, 2, 11, 3]
[5, 2, 11, 3, 331]
[5, 2, 11, 3, 331, 19]
[5, 2, 11, 3, 331, 19, 199]
[5, 2, 11, 3, 331, 19, 199, 53]
[5, 2, 11, 3, 331, 19, 199, 53, 21888927391]
[5, 2, 11, 3, 331, 19, 199, 53, 21888927391, 29833]
...
# 소수 목록 {2}에서 시작했을 때의 결과...
[2, 3]
[2, 3, 7]
[2, 3, 7, 43]
[2, 3, 7, 43, 13]
[2, 3, 7, 43, 13, 53]
[2, 3, 7, 43, 13, 53, 5]
[2, 3, 7, 43, 13, 53, 5, 6221671]
[2, 3, 7, 43, 13, 53, 5, 6221671, 38709183810571]
...
이 이상은 숫자가 너무 커서 컴퓨터에서 처리하는 데 시간이 많이 걸림
'''