Project Euler #5
문제
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?2520은 1부터 10까지의 모든 수로 나누어 떨어지는 가장 작은 수이다 .(1 ~ 10의 최소공배수)
1부터 20까지의 모든 수로 나누어 떨어지는 가장 작은 수는 무엇인가?
풀이 1
해당 문제는 1부터 20까지의 수들에 대한 최소공배수를 구하는 문제이다.
1은 제외해도 된다.(2 ~ 20까지의 수)
최소공배수는 주어진 수를 소인수 분해한 결과 중 소수의 지수가 큰 수들을 곱한 값이다.
이것들을 가지고 잘 섞어서 풀었다.
import time
num = 20
pl = [2] #2는 유일한 짝수인 소수
rs = []
x = 1
stime = time.time() #시작 시간
for i in range(3, num + 1, 2): #1 ~ num까지의 모든 소수 계산(2를 제외한 모든 소수는 홀수다.)
for j in range(3, i + 1, 2):
if i % j == 0 and j != i:
break
elif i % j == 0 and j == i: #소수 여부를 판단.
pl.append(i)
for k in pl:
l = 1
while pow(k, l) < num: #구간내의 소수의 거듭제곱
rs.append(k)
x *= k #소수들의 곱으로 최소공배수 계산
l += 1
print(rs, x)
print(time.time() - stime) #수행 시간
풀이 2
- 이번엔 에라토스테네스의 체를 이용한다.
에라토스테네스의 체
- 에라토스테네스가 고안해낸 특정 수 이하의 모든 소수를 구하는 알고리즘이다.
- 여기서 특정 수는 2이상의 자연수이다.
- 구하는 순서는 아래와 같다.
1. 2에서 구하는 수()까지의 정수를 순서대로 나열한다.
(다음을 만족 하는 수열로 나타낼 수 있다.
)
2. 위 수열에서 첫번째 수를 선택한다.(2가 선택된다.)
3.2단계
에서 선택된 수(2)를 제외한 나머지 배수(4, 6, …)를 수열에서 제거한다.
4. 다시 수열에서 두번째 수를 선택한다.(2단계
의 반복, 3이 선택된다.)
5.3단계
에서 선택된 수(3)를 제외한 나머지 배수(6, 9, …)를 수열에서 제거한다.(3단계
의 반복)
6. 수열의 마지막까지 위의2 ~ 5 단계
를 반복한다.
7. 수열의 남은 수가 모두 소수이다.
import time
num = 20000
rs = 1
SE = [0]*(num + 1)
SE[0:2] = [1] * 2 #0과 1은 소수가 아니다.
stime = time.time() #시작 시간
for idx, ck in enumerate(SE): #에라토스테네스의 체 구현
if ck == 0:
SE[idx * 2::idx] = [1] * ((num // idx) - 1)
for idx, ck in enumerate(SE):
if ck == 0:
power = 1
while power <= num: #구간내의 소수의 거듭제곱
power *= idx #소수들의 곱으로 최소공배수 계산
rs *= power // idx
print(rs)
print(time.time() - stime) #수행 시간
후기
최소공배수를 활용한 부분을 제외하면 크게 어려운 부분은 없다.
앞으로도 소수에 대한 문제가 있을 때 에라토스테네스의 체가 자주 사용될 것 같다.
'프로젝트 오일러' 카테고리의 다른 글
Project Euler #7 (0) | 2017.02.09 |
---|---|
Project Euler #6 (0) | 2017.02.08 |
Project Euler #4 (0) | 2017.02.06 |
Project Euler #3 (0) | 2017.02.05 |
Project Euler #2 (0) | 2017.02.04 |
댓글