가장 큰 소인수 구하기, 소수의 합 구하기
글쓴이: 익명 사용자 / 작성시간: 토, 2020/03/28 - 2:01오후
재미와 공부삼아 오일러 프로젝트를 풀고 있습니다. https://projecteuler.net/
아래 두 문제를 풀고 있는데, 두 문제 모두 답을 알아내기에 적합한 코드를 작성한 것 같지만, 시간이 너무 오래 걸립니다. 그래서 여러분이라면 어떻게 작성하실지 궁금합니다. mutiprocess를 사용하지 않고 빠르게 계산할 수 있는 방법이 어떤게 있을 수 있을지 궁금합니다.
제 생각에 isPrime 함수를 좀 고쳐서 빠르게 만들어야 할 것 같은데........
참고로 숙제 절대 아닙니다.
문제 3:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143 ?
제가 작성한 코드
23 def isPrime(num): 24 if num == 2: 25 return True 26 for i in range(2, num): 27 if num % i == 0: 28 return False 29 return True 30 31 for i in range(600851475143, 1, -1): 32 if 600851475143 % i == 0 and isPrime(i): 33 print(i) 34 break
문제 10:
The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.
Find the sum of all the primes below two million.
제가 작성한 코드
67 def isPrime(num): 68 if num == 2: 69 return True 70 for i in range(2,num): 71 if num % i == 0: 72 return False 73 return True 74 75 sum_of_prime = 0 76 for i in range(2, 2000000): 77 if isPrime(i): 78 sum_of_prime += i 79 print(sum_of_prime)
Forums:
26 for i in range(2, num)
요 구간을 2부터 다시 할게 아니라 소수로만 나눠도 될 것 같은데요. "합성수(合成數, composite number)는 약수의 개수가 3개 이상인 자연수로 둘 이상의 소수를 곱한 수이다"를 바탕으로 접근하시면 될거 같은데 input 값이 워낙 커서 별로 도움될거 같지도 않습니다.
---------------
Happy Hacking!
문제3의 경우...
문제3의 경우...
num이 소수인지 검사를 할 때, 2부터 num-1까지 다 검사할 필요는 없고 num의 제곱근, sqrt(num) 까지만 검사하면 충분합니다. sqrt(num)보다 크고 num보다는 작은 약수 a가 존재한다면 a*b = num이 되는 또 하나의 약수 b는 반드시 sqrt(num)보다 작을 테니까요. isPrime내의 루프가 원래 돌 횟수의 제곱근으로 줄어들긴 하겠지만 이건 num이 소수일 때만 이득을 제대로 볼 것이고...
그리고 600851475143 가 홀수이니 절대로 짝수로 나눠떨어지는 일은 없겠지요. 따라서 range()의 세번째 인자가 -1이 아니라 -2면 되고 이것만으로 루프 절반을 줄일 수는 하겠네요.
그런데 이 두 가지는 루프 숫자를 많이 줄이기는 할 텐데 여전히 오래 걸리기는 매한가지일 테고요.
아예 sqrt(600851475143) ~ 775146 이하의 소수를 죄다 계산한 다음 그것들로만 나눠볼 수도 있겠죠. 이 정도 규모라면 에라토스테네스의 체를 쓰는 것만으로도 충분할 것 같고요.
힌트를 하나 드리자면, 예를 들어 1296을 가지고 저 코드를 돌리면 1296부터 1까지 거슬러 내려가며 검사를 할 것이고, 그 과정에서 최대 25번 1296 % i == 0 검사를 통과할 텐데, 이 문제의 답은 고작 3입니다.
1296 = 2^4 * 3^4
즉, 사실은 isPrime()의 속도를 빠르게 하는 게 문제가 아니라는 거죠. 여기서 답 3을 어떻게 빠르게 찾을 수 있을지 생각해보시면 좋을 듯 합니다.
사실 이렇게 잘난 척 말할 수 있는 건 제 디스크 깊숙히 제가 저 문제를 풀던 코드가 남아 있어서... ^_ㅠ
좋은 하루 되세요!
10번은
10번은 제 생각엔 k이하의 모든 소수의 집합 P(k)가 주어진다고 가정하고, k+1이 P(k)의 원소 가운데 어느 하나로 나눠지는지 체크한 다음, 떨어진다면 P(k+1) := P(k), 아니라면 P(k+1) = {k+1} U P(k)로 P(k+1)을 업데이트 하는 방향으로 가는 게 빠르지 않을까 싶습니다. 2백만 이하의 소수는 많지 않을 것으로 보이거든요.
python
3번은
저도 흥미가 가서 좀 생각해 보려고 하는데, 주의할 점은 N = A * B, 1 < A <= B인 경우 B가 소수일 수도 있습니다. B를 찾기 위해 N-1부터 2까지 차례로 나눠볼 필요는 없고 sqrt(N)보다 작거나 같은 최대의 정수부터 나눠보면 되기는 합니다만, 이건 기본적으로 A들을 찾는 것인데 B가 소수인지는 별도로 확인해야 합니다.
그리고 B가 소수라면 더 이상 어떤 계산도 할 필요가 없기 때문에 기본적으로는 top down 방식의 dynamic programming일 것 같습니다.
...
대충대충....
그냥 깊은 고민 없이 에라스토테네스의 체 써서 뚝딱 풀었습니다.
이거 원, 너무 대충 짰군요. 고쳐서 올립니다.
이거 원, 너무 대충 짰군요. 고쳐서 올립니다.
소수 식별 산법 나름 구현해봤어요~
[우분투 18.04 파여폭스 나비에서 작성했어요~]
--
^고맙습니다 감사합니다_^))//
코딩 후에 전체글 쭈우욱 훓어보니 OP(원질문하신분
코딩 후에 전체글 쭈우욱 훓어보니 OP(원질문하신분)와 산법이 똑같네요~^^^
그래도 기쁘네요,,, 태어나서 처음으로 고민해본 소수 식별 산법이었어요~
감사합니다^^^
[우분투 18.04 파여폭스 나비에서 작성했어요~]
속도를 좀 더 빠르게 산법 보완합니다 ;;;
처음에 짠 코드와 비교를 했습니다.
출력결과는 diff 뜨서 확인했구요. 두 코드 모두 출력결과 동일합니다.
속도 비교위한 시간 확인 코드를 내부에 삽입했습니다.
10만개의 범위내에서 소수 식별하는데 걸린 소요시간이 다음과 같아요:
첫번째코드: 1분 51초
두번째코드: 13초
[우분투 18.04 파여폭스 나비에서 적었어요~]
--
^고맙습니다 감사합니다_^))//
파이선님 가시는 길에 루비가 곁을 고이 지켜드려야
파이선님 가시는 길에 루비가 곁을 고이 지켜드려야 하는데...제가 요새 넘 바뻐서 ㅠㅠ
^^^
익명루비님 코로나정국 잘 견뎌내시고 늘 건강하십시오^^^
파이썬3 드림
[우분투 18.04 파여폭스 나비에서 댓글적었어요~]
최고로 단순한 코드로 승부합니다.irb(main)
최고로 단순한 코드로 승부합니다.
음하하하
뭔지 모르겠지만 익명루비님의 성공입니다^^^
뭔지 모르겠지만 익명루비님의 성공입니다^^^
헌데 정확히 이건 파이썬의 실패가 아니라 저 개인의 실패이구요,,,
곁가지로,,, 저기위에 일반산법만 C언어로 코딩해서 실행속도(10만까지의 범위)를 비교했더니...
파이썬3(일반산법): 1분 3초
C언어(일반산법): 1초~2초
그래서 사람들이 C언어 C언어 하는구나라고 느꼈어요..
태어나서 처음으로 짜본 C코드에서
말로만 들었던 C언어의 빠른속도에 깜짝 놀랩니다,,,
동기부여해주신 익명루비님께 감사요~^^^
파이썬3 드림
[우분투 18.04 파여폭스 나비에서 적었어유]
저 위에 파이썬 속도 보완 산법을 C언어로 옮겼어요.
저 위에 파이썬 속도 보완 산법을 C언어로 옮겼어요. 좀 빡세더이다,,,
동적배열(malloc) 구현엔 실패하고,
아주그냥 10만개 범위내에서만 테스트 할 수 있게끔 짰습니다.
일반산법의 C코드와 비교해서 1초 가량 시간을 단축시켜주네요.
일반산법(C언어): 1.732 초
보완산법(C언어): 0.329 초
꾸벅,,,
[우분투 18.04 파여폭스 나비에서 적었어요~]
설거지^^^
지금까지 실험한 것들,,,
파이썬(일반산법/보완산법)
씨언어(일반산법/보완산법)
4개의 코드 [***] 를 교통정리하여 깃랩에 올려두었어요~
혹시나 저처럼 코딩 공부하시는분들을 위하야 공유합니다,,,
꾸벅,,, 파이썬3 드림
[***] 소수 식별 산법:
https://gitlab.com/soyeomul/test/-/tree/master/%EC%86%8C%EC%88%98_%EC%8B%9D%EB%B3%84
[우분투 18.04 파여폭스 나비에서 적었어요~]
--
^고맙습니다 감사합니다_^))//
말록 성공했어요!!!
동적배열 적용한 코드[***] 좀 전에 성공했습니다.
동적배열 적용하려 씨언어 포인터/배열 한달 공부했네요
공부해보니 씨언어는 진짜 업자(業者)분들께서만 다루는 언어 맞는거 같아요.
씨언어 너무 어렵습니다...
파이썬3 드림
[***] https://gitlab.com/soyeomul/test/-/raw/master/%EC%86%8C%EC%88%98_%EC%8B%9D%EB%B3%84/8.c
[우분투 18.04 파여폭스 나비에서 적었습니다]
[실험 스샷 첨부했습니다 -- 5월 30일]
--
^고맙습니다 감사합니다_^))//
마지막입니다 ;;;
다시는 C언어를 손대지 않을께요,,,
https://gitlab.com/soyeomul/test/-/commit/8b6b4982bcf9ad1bdd77a31603f4a5df2fec2c98
파이썬3 드림
^고맙습니다 감사합니다_^))//
[우분투 18.04 파여폭스 나비에서 적었어요~]
그래두 한번 배워놓으면 여러모로 쓸모있는 언어가
그래두 한번 배워놓으면 여러모로 쓸모있는 언어가 c인데요~~
그러면 루비 배우세요~~~~~~~ㅋㅋ
아이고 감사합니다~~~
C언어로 소수 구하는 물건이 제대로 동작하는것만해도 너무 다행이라 생각합니다;;;
C언어로는 정말 더이상 바랄게 없네요;;;
차후 하게될 농장 데이타를 JSON 포맷으로의 재구성에만 집중하고프네요,,,
(대략 파이썬로 작업할거 같아요~)
부족한 농사꾼에게 소중한 댓글 감사드립니다 호동님^^^
파이썬3 드림
[크롬북에서 적었어요~]
질문이요.
파이썬3 님이 황병희 님 인가요?
세벌 https://sebuls.blogspot.kr/
예 세벌님~
[우분투 18.04 파여폭스 나비에서 적었어요~]
--
^고맙습니다 감사합니다_^))//
아.. 그리고...
아.. 그리고...
로제타코드라고... 함 살펴보세요
http://rosettacode.org/wiki/Prime_decomposition
수학 이런할 할 능력이 안 되서 로제타코드에서
수학 이런할 할 능력이 안 되서 로제타코드에서 베껴와서 테스트했습니다.
http://rosettacode.org/wiki/Prime_decomposition#Ruby
https://www.gnu.org/licenses/old-licenses/fdl-1.2.html
Content is available under GNU Free Documentation License 1.2 unless otherwise noted.
사용 CPU: AMD Athlon 3000G
루비코드 속도가 어마무시하네여~
루비코드 속도가 어마무시하네여~
훌륭한 코드에 감사드립니다^^^
[우분투 18.04 파여폭스 나비에서 적었어요~]
댓글 달기