~cpp
for eachGenNumberFour in GenNumbersFour
isAllPrimeNumber:
print eachGenNumberFour
return
print "impossible"
GenNumbersFour = 합이 x 인 수 조합리스트
~cpp
class PrimeNumberList:
def __init__(self,aNum):
self.size = aNum
self.resultTable = []
self.createList()
def createList(self):
for i in range(2,self.size+1):
if self.isPrimeNumber(i):
self.resultTable.append(i)
def isPrimeNumber(self,aNum):
for eachValue in self.resultTable:
if aNum % eachValue == 0:
return False
return True
def getList(self):
return self.resultTable
class PrimeNumberTest(unittest.TestCase):
def testPrimeNumber(self):
self.assertEquals([2,], PrimeNumberList(2).getList())
self.assertEquals([2,3], PrimeNumberList(3).getList())
self.assertEquals([2,3,5], PrimeNumberList(5).getList())
self.assertEquals([2,3,5,7,11], PrimeNumberList(12).getList())
self.assertEquals([2,3,5,7,11,13,17,19], PrimeNumberList(20).getList())
그리고 소수리스트로부터 4개를 구하는 방법에 대해 생각하다. 맨 처음에 대해서는 중복을 허용하면 안되는 줄 알고 구현하였다. 그러다가 문제에서 중복을 허용한다는 사실을 알고 다시 구현.~cpp
def selectionFour(aList):
sizeOfList = len(aList)
for i in range(sizeOfList):
for j in range(sizeOfList):
for k in range(sizeOfList):
for l in range(sizeOfList):
yield [aList[i],aList[j],aList[k],aList[l]]
~cpp
from __future__ import generators
import psyco
class PrimeNumberList:
def __init__(self,aNum):
self.size = aNum
self.resultTable = []
self.createList()
def createList(self):
for i in range(2,self.size+1):
if self.isPrimeNumber(i):
self.resultTable.append(i)
def isPrimeNumber(self,aNum):
for eachValue in self.resultTable:
if aNum % eachValue == 0:
return False
return True
def getList(self):
return self.resultTable
def selectionFour(aList):
sizeOfList = len(aList)
for i in range(sizeOfList):
for j in range(sizeOfList):
for k in range(sizeOfList):
for l in range(sizeOfList):
yield [aList[i],aList[j],aList[k],aList[l]]
def main():
n = int(raw_input('input number : '))
primeNumberList = PrimeNumberList(n)
for eachPrimeNumberSeq in selectionFour(primeNumberList.getList()):
if sum(eachPrimeNumberSeq) == n:
print eachPrimeNumberSeq
return
print "Impossible"
if __name__=="__main__":
#unittest.main(argv=('','-v'))
psyco.full()
main()
~cpp
C:\WINDOWS\system32\cmd.exe /c python SummationOfFourPrimes.py
input number : 10000
[2, 2, 23, 9973]
21065 function calls in 6.387 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.075 0.075 1.201 1.201 summationoffourprimes.py:13(createList)
0 0.000 0.000 profile:0(profiler)
1 5.103 5.103 6.387 6.387 summationoffourprimes.py:88(main)
1 0.000 0.000 1.201 1.201 summationoffourprimes.py:8(__init__)
9999 1.126 0.000 1.126 0.000 summationoffourprimes.py:18(isPrimeNumber)
1 0.000 0.000 0.000 0.000 summationoffourprimes.py:24(getList)
11061 0.083 0.000 0.083 0.000 summationoffourprimes.py:79(selectionFour)
1 0.000 0.000 6.387 6.387 <string>:1(?)
~cpp
C:\WINDOWS\system32\cmd.exe /c python SummationOfFourPrimes.py
input number : 50000
[2, 2, 3, 49993]
60269 function calls in 24.926 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.428 0.428 19.348 19.348 summationoffourprimes.py:13(createList)
0 0.000 0.000 profile:0(profiler)
1 5.492 5.492 24.923 24.923 summationoffourprimes.py:88(main)
1 0.000 0.000 19.348 19.348 summationoffourprimes.py:8(__init__)
49999 18.920 0.000 18.920 0.000 summationoffourprimes.py:18(isPrimeNumber)
1 0.000 0.000 0.000 0.000 summationoffourprimes.py:24(getList)
10265 0.083 0.000 0.083 0.000 summationoffourprimes.py:79(selectionFour)
1 0.003 0.003 24.926 24.926 <string>:1(?)
Hit any key to close this window...
대부분의 시간은 소수테이블을 작성하는 부분이 된다. 그래서 이 부분에 대해서 ~cpp
C:\WINDOWS\system32\cmd.exe /c python SummationOfFourPrimes.py
input number : 10000
[2, 2, 23, 9973]
11067 function calls in 5.417 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 summationoffourprimes.py:48(getList)
1 0.000 0.000 5.417 5.417 <string>:1(?)
1 0.000 0.000 0.013 0.013 summationoffourprimes.py:36(createList)
1 0.000 0.000 0.013 0.013 summationoffourprimes.py:31(__init__)
11061 0.094 0.000 0.094 0.000 summationoffourprimes.py:103(selectionFour)
1 5.309 5.309 5.416 5.416 summationoffourprimes.py:112(main)
1 0.013 0.013 0.013 0.013 summationoffourprimes.py:8(prime2)
Hit any key to close this window...
~cpp
C:\WINDOWS\system32\cmd.exe /c python SummationOfFourPrimes.py
input number : 50000
[2, 2, 3, 49993]
10271 function calls in 7.878 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 summationoffourprimes.py:48(getList)
1 0.002 0.002 7.878 7.878 <string>:1(?)
1 0.002 0.002 0.090 0.090 summationoffourprimes.py:36(createList)
1 0.000 0.000 0.090 0.090 summationoffourprimes.py:31(__init__)
10265 0.098 0.000 0.098 0.000 summationoffourprimes.py:103(selectionFour)
1 7.688 7.688 7.876 7.876 summationoffourprimes.py:112(main)
1 0.088 0.088 0.088 0.088 summationoffourprimes.py:8(prime2)
Hit any key to close this window...
최적화 이후 50000번 기준으로는 병목에 대한 변별력이 없다.~cpp
C:\WINDOWS\system32\cmd.exe /c python SummationOfFourPrimes.py
input number : 1000000
[2, 2, 13, 999983]
470994 function calls in 26.768 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 summationoffourprimes.py:48(getList)
1 0.040 0.040 26.768 26.768 <string>:1(?)
1 0.062 0.062 2.708 2.708 summationoffourprimes.py:36(createList)
1 0.000 0.000 2.708 2.708 summationoffourprimes.py:31(__init__)
470988 5.244 0.000 5.244 0.000 summationoffourprimes.py:103(selectionFour)
1 18.777 18.777 26.728 26.728 summationoffourprimes.py:112(main)
1 2.646 2.646 2.646 2.646 summationoffourprimes.py:8(prime2)
Hit any key to close this window...
~cpp
C:\WINDOWS\system32\cmd.exe /c python SummationOfFourPrimes.py
input number : 1000000
(2, 2, 13, 999983)
6 function calls in 16.671 CPU seconds
Random listing order was used
ncalls tottime percall cumtime percall filename:lineno(function)
0 0.000 0.000 profile:0(profiler)
1 0.000 0.000 0.000 0.000 summationoffourprimes.py:48(getList)
1 13.736 13.736 16.540 16.540 summationoffourprimes.py:121(main2)
1 0.067 0.067 2.804 2.804 summationoffourprimes.py:36(createList)
1 2.738 2.738 2.738 2.738 summationoffourprimes.py:8(prime2)
1 0.131 0.131 16.671 16.671 <string>:1(?)
1 0.000 0.000 2.804 2.804 summationoffourprimes.py:31(__init__)
Hit any key to close this window...
10000000 건에 대해서는 7.49 초 기록 (profiler 를 이용할 경우 속도저하가 있기 때문에 profiler 를 끄고 psyco 만으로 실행)~cpp
def selectionFour(aList,aNum):
sizeOfList = len(aList)
for i in range(sizeOfList):
for j in range(sizeOfList):
for k in range(sizeOfList):
for l in range(sizeOfList):
expectedLastValue = aNum-(aList[i]+aList[j]+aList[k])
if expectedLastValue in aList:
yield [aList[i],aList[j],aList[k],expectedLastValue]
else:
break
inlining 을 하지 않았음에도 6.4초대를 기록하였다. inlining 을 하면 5.7초대를 기록한다.