피보나치 수열에서 1000자리를 넘어가는 첫번째 항은?
포럼에는 역시 기발한 방법들이 있지만, 여기서는 나이브하게...
Monday, April 20, 2015
Project Euler #24 - 100만번째 permutation
0~9의 permutation 으로 만들 수 있는 숫자들을 차례로 늘어놓았을 때, 100만번째 수는?
1번째는 0123456789
9!+1번째는 1023456789
9!*2+1번째는 2013456789
그럼 제일 앞에 2를 고정하고, 9개의 숫자로 permutation을 만들었을 때 100만 - 9!*2 번째 숫자를 찾는 문제로 바뀐다.
코드로 표현하면,
factorial = {1:1} for i in range(2,10): factorial[i] = i*factorial[i-1] answer = '' d = range(10) N = 1000000-1 for i in range(9,0,-1): answer += str(d.pop(N / factorial[i])) N %= factorial[i] print answer + str(d[0])
Project Euler #23 - Non-abundant sums
Non-abundant sums: 두 개의 abundant numbers(자기 자신을 뺀 약수의 합이 자기 자신 보다 커지는 숫자)를 더해서 만들 수 없는 숫자들의 합은?
문제에서 28123보다 큰 수는 모두 두 개의 a.n 합으로 표현할 수 있다고 했으니 그보다 작은 수만 체크하면 된다. 두 개의 a.n 로 만들 수 "없는" 것보다는 만들 수 "있는" 쪽을 찾는 게 쉬워 보인다.
sympy를 쓰면 어렵지 않다.
역시나 다른 문제들처럼 소수-소인수분해-약수합 부분을 직접 구현하면 약간 빨라진다. 하지만 abundant number 를 찾는 부분보다, 그 숫자들로 조합을 만드는 부분이 오래 걸리는 거라 큰 개선은 없다.
문제에서 28123보다 큰 수는 모두 두 개의 a.n 합으로 표현할 수 있다고 했으니 그보다 작은 수만 체크하면 된다. 두 개의 a.n 로 만들 수 "없는" 것보다는 만들 수 "있는" 쪽을 찾는 게 쉬워 보인다.
sympy를 쓰면 어렵지 않다.
from sympy import divisors abun = [] for i in range(12,28123): if sum(divisors(i)[:-1]) > i: abun.append(i) allabuncomb = [True] * 28123 for i,a in enumerate(abun): for b in abun[i:]: if a+b >= 28123: break allabuncomb[a+b] = False print sum([n for n in range(28123) if allabuncomb[n]])
역시나 다른 문제들처럼 소수-소인수분해-약수합 부분을 직접 구현하면 약간 빨라진다. 하지만 abundant number 를 찾는 부분보다, 그 숫자들로 조합을 만드는 부분이 오래 걸리는 거라 큰 개선은 없다.
def rwh_primes1(n): # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188 """ Returns a list of primes < n """ sieve = [True] * (n/2) for i in xrange(3,int(n**0.5)+1,2): if sieve[i/2]: sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1) return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]] def factor(n,pn): rs = {} for p in pn: if n % p == 0: cnt = 0 while n % p == 0: n /= p cnt += 1 rs[p] = cnt if n == 1: return rs if p*p > n: rs[n] = 1 return rs def isAbun(n,pn): fDic = factor(n,pn) dn = 1 for k in fDic: dn *= sum([k**i for i in range(fDic[k]+1)]) return (dn - n > n) pn = rwh_primes1(28123) abun = [] for n in range(12,28123): if isAbun(n,pn): abun.append(n) allabuncomb = [True] * 28123 for i,a in enumerate(abun): for b in abun[i:]: if a+b >= 28123: break allabuncomb[a+b] = False print sum([n for n in range(28123) if allabuncomb[n]])
Project Euler #22 - 이름 숫자
알파벳을 숫자로 변환하고 주어진 공식으로 순위와의 가중합을 구하는 문제
포럼에 올라온 글에 자극받아서 아예 한 줄 코드로 만들어 봤다.
ord는 문자에 해당하는 아스키번호를 알려주는 함수라고 한다.
아래와 같이 정상적인(?) 코드를 작성할 수도 있다.
포럼에 올라온 글에 자극받아서 아예 한 줄 코드로 만들어 봤다.
print sum([(i+1)*sum([ord(c)-64 for c in name]) for i,name in enumerate(sorted([name.strip('"') for name in open('p022_names.txt').read().split(',')]))])
아래와 같이 정상적인(?) 코드를 작성할 수도 있다.
ABC = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' alphanum = {} for i,c in enumerate(ABC): alphanum[c] = i + 1 def calcname(name): return sum([alphanum[s] for s in name]) with open('/Users/Dongug/Downloads/p022_names.txt') as f: names = [name.strip('"') for name in f.readline().split(',')] rs = 0 for i,name in enumerate(sorted(names)): rs += (i + 1) * calcname(name) print rs
Sunday, April 19, 2015
Project Euler #21 - amicable numbers
10000이하의 친화수를 찾는 문제
sympy의 divisors함수를 쓰면 쉽다.
10000까지 반복해서 소인수분해를 해야 하는데, 좀 더 빠르게 하려면 소수를 직접 찾고, 소인수 분해를 직접 한 다음에, 약수의 합을 계산하면 된다.
마지막 스텝은 중학교 때 배운 공식 24 = 2^3 * 3 => 24의 약수의 합=(1+2+4+8)*(1+3)=1+2+4+8+3+6+12+24 를 쓰면 된다.
코드는 길어지지만 실행시간은 1/4로 줄어든다.
sympy의 divisors함수를 쓰면 쉽다.
from sympy import divisors d_nDic = {} for i in range(3,10000): d_nDic[i] = sum(divisors(i))-i ami = [] for i in d_nDic: if d_nDic[i] > 3 and d_nDic[i] < 10000: if i == d_nDic[d_nDic[i]] and i != d_nDic[i]: ami.append(i) print sum(ami)
10000까지 반복해서 소인수분해를 해야 하는데, 좀 더 빠르게 하려면 소수를 직접 찾고, 소인수 분해를 직접 한 다음에, 약수의 합을 계산하면 된다.
마지막 스텝은 중학교 때 배운 공식 24 = 2^3 * 3 => 24의 약수의 합=(1+2+4+8)*(1+3)=1+2+4+8+3+6+12+24 를 쓰면 된다.
코드는 길어지지만 실행시간은 1/4로 줄어든다.
def rwh_primes1(n): # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188 """ Returns a list of primes < n """ sieve = [True] * (n/2) for i in xrange(3,int(n**0.5)+1,2): if sieve[i/2]: sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1) return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]] def factor(n,pn): rs = {} for p in pn: if n % p == 0: cnt = 0 while n % p == 0: n /= p cnt += 1 rs[p] = cnt if n == 1: return rs if p*p > n: rs[n] = 1 return rs def d_n(n,pn): fDic = factor(n,pn) dn = 1 for k in fDic: dn *= sum([k**i for i in range(fDic[k]+1)]) return dn - n pn = rwh_primes1(10000) d_nDic = {} for i in range(3,10000): d_nDic[i] = d_n(i,pn) ami = [] for i in d_nDic: if d_nDic[i] > 3 and d_nDic[i] < 10000: if i == d_nDic[d_nDic[i]] and i != d_nDic[i]: ami.append(i) print sum(ami)
Project Euler #20 - 100!의 숫자 합
100!의 각 자리수의 합은?
파이썬이 아니라면 고민스럽겠지만...
마지막에 range(1,101)보다는 range(1,100)이 조금 더 이뻐 보여서..
파이썬이 아니라면 고민스럽겠지만...
from operator import mul print sum([int(s) for s in str(reduce(mul,range(1,100)))])
마지막에 range(1,101)보다는 range(1,100)이 조금 더 이뻐 보여서..
Project Euler #19 - 1일 일요일이 몇 번?
1901년부터 2000년까지 매달 1일이 일요일인 경우는 몇 번?
1. 1200번 중 몇 번인지를 물어보는 문제인데, 100년이면 충분히 긴 시간이고 중심극한정리를 생각하면 정답은 1200/7 = 171.xx 근처에 있을 거다.
2. 1번으로 풀면 cheating인 듯 하고.. 이런 코드를 짜 봤다. 매달 1일이 무슨 요일인지 다 찾아보는 방법이다.
3. 포럼에서 본 글 중 인상적인 것.
(일단, 윤년이 아닌 경우)
1월 1일이 일요일인 경우 그 해에 1일이 일요일은 몇 번?
1월 1일이 월요일인 경우 그 해에 1일이 일요일은 몇 번?
이걸 미리 찾아두고, 100년 동안 1월 1일이 일요일이었던 횟수, 월요일이었던 횟수, ... 를 세어 본다. 2번에서는 y*m번의 요일 계산이 필요했지만 3번은 y+m번의 요일 계산이면 충분하다.
1. 1200번 중 몇 번인지를 물어보는 문제인데, 100년이면 충분히 긴 시간이고 중심극한정리를 생각하면 정답은 1200/7 = 171.xx 근처에 있을 거다.
2. 1번으로 풀면 cheating인 듯 하고.. 이런 코드를 짜 봤다. 매달 1일이 무슨 요일인지 다 찾아보는 방법이다.
d = 2 #Monday - 1 Jan 1901 c = 0 for year in range(1901,2001): for mon in range(1,13): if d == 0: c += 1 if mon in (1,3,5,7,8,10,12): d = (d + 3) % 7 elif mon in (4,6,9,11): d = (d + 2) % 7 elif year % 4 == 0: d = (d + 1) % 7 print c
3. 포럼에서 본 글 중 인상적인 것.
(일단, 윤년이 아닌 경우)
1월 1일이 일요일인 경우 그 해에 1일이 일요일은 몇 번?
1월 1일이 월요일인 경우 그 해에 1일이 일요일은 몇 번?
1월 1일이 화요일인 경우 그 해에 1일이 일요일은 몇 번?
...
1월 1일이 토요일인 경우 그 해에 1일이 일요일은 몇 번?
Project Euler #18 - Maximum path sum I
최대합 경로 문제
처음엔 이렇게 풀었다.
포럼 글을 읽다보니.. 삼각형을 뒤집으면 문제가 훨씬 쉽게 풀린다.
처음 이런 코드를 작성할 때는 어떤 리스트의 몇번째 위치에 어떤 값이 들어 있는지 헷갈려서 머리 싸매고 했었는데.. 100번까지 풀고 블로그 정리용으로 다시 작성하니까 훨씬 쉽다. 조금이나마 발전이 있는 것 같아서 기분 up.
처음엔 이렇게 풀었다.
st = '''75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23''' og = [] for line in st.split('\n'): og.append([int(e) for e in line.split()]) for i in range(len(og)-1): og[i+1][0] = og[i][0] + og[i+1][0] for j in range(len(og[i])-1): og[i+1][j+1] = max(og[i][j],og[i][j+1]) + og[i+1][j+1] og[i+1][-1] = og[i][-1] + og[i+1][-1] print max(og[-1])
포럼 글을 읽다보니.. 삼각형을 뒤집으면 문제가 훨씬 쉽게 풀린다.
st = '''75 95 64 17 47 82 18 35 87 10 20 04 82 47 65 19 01 23 75 03 34 88 02 77 73 07 63 67 99 65 04 28 06 16 70 92 41 41 26 56 83 40 80 70 33 41 48 72 33 47 32 37 16 94 29 53 71 44 65 25 43 91 52 97 51 14 70 11 33 28 77 73 17 78 39 68 17 57 91 71 52 38 17 14 91 43 58 50 27 29 48 63 66 04 68 89 53 67 30 73 16 69 87 40 31 04 62 98 27 23 09 70 98 73 93 38 53 60 04 23''' og = [[int(e) for e in line.split()] for line in st.split('\n')][::-1] l = len(og) for i in range(l): for j in range(l - i-1): og[i+1][j] += max(og[i][j],og[i][j+1]) print og[-1][-1]
처음 이런 코드를 작성할 때는 어떤 리스트의 몇번째 위치에 어떤 값이 들어 있는지 헷갈려서 머리 싸매고 했었는데.. 100번까지 풀고 블로그 정리용으로 다시 작성하니까 훨씬 쉽다. 조금이나마 발전이 있는 것 같아서 기분 up.
Project Euler #17 - 숫자 읽기
1000까지의 숫자를 영어로 쓸 때 필요한 알파벳의 수는?
성실과 근면을 요구하는 문제.. forty인지 fourty인지 헷갈리는 ESL 입장에선 약간 짜증나는 문제.
글타래를 읽다 보니.. 요런 스타일의 코드가 있다.
귀찮은 정도는 똑같지만, 답이 틀렸을 때 틀린 부분을 찾기가 좀 더 쉬울 것 같다.
성실과 근면을 요구하는 문제.. forty인지 fourty인지 헷갈리는 ESL 입장에선 약간 짜증나는 문제.
d1 = ['one','two','three','four','five','six','seven','eight','nine'] d2 = ['ten','eleven','twelve','thirteen','fourteen','fifteen','sixteen','seventeen','eighteen','nineteen'] d3 = ['twenty','thirty','forty','fifty','sixty','seventy','eighty','ninety'] d4 = ['hundred','and','thousand'] l1 = [len(e) for e in d1] l2 = [len(e) for e in d2] l3 = [len(e) for e in d3] l4 = [len(e) for e in d4] # 1~99 s1 = sum(l1)*9 + sum(l2) + sum(l3)*10 # 1~99 101~199 ... 901~999 s2 = s1*10 + sum(l1)*99 + sum(l4[:2])*99*9 # 1~1000 s3 = s2 + sum(l1) + l4[0]*9 + l1[0] + l4[2] print s3
글타래를 읽다 보니.. 요런 스타일의 코드가 있다.
def read(n): ... return ... sm = 0 for i in range(1,1001): sm += len(read(n)) print sm
귀찮은 정도는 똑같지만, 답이 틀렸을 때 틀린 부분을 찾기가 좀 더 쉬울 것 같다.
Project Euler #16 - Power digit sum
2^1000 의 숫자들을 다 더하면?
300자리 정도 되겠지만 큰 정수에 강한 파이썬을 믿어보자~
2**1000000 계산은 위의 코드보다 빠른 방법이 있는데.. 1000제곱 정도는 이것보다 빠른 방법을 못 찾겠다.
300자리 정도 되겠지만 큰 정수에 강한 파이썬을 믿어보자~
print sum([int(s) for s in str(2**1000)])
2**1000000 계산은 위의 코드보다 빠른 방법이 있는데.. 1000제곱 정도는 이것보다 빠른 방법을 못 찾겠다.
Project Euler #15 - Lattice paths
격자 이동 - 20*20인 격자의 왼쪽 위에서 오른쪽 아래로 가는 경로는 몇가지인가? 단, 오른쪽, 아래로만 이동할 수 있다.
오른쪽으로 20칸, 아래로 20칸 이동하는 문제이다. 40번 이동/20번 오른쪽/20번 아래쪽은 변함이 없다. 40칸의 자리가 있고, 그 중 오른쪽으로 이동할 20칸을 어떻게 할당하느냐의 문제이고 간단히 40C20을 계산하면 된다.
40!/20!/20! 계산 문제인데.. 40!는 큰 숫자이고 다른 언어라면 큰 숫자의 메모리/정확도 문제 때문에.. 40/20*39/13/3*38/19/2*.... 이런 걸 만들어야 할 수도 있다. 하지만 파이썬은 큰 정수를 다루는 데 전혀~ 문제가 없다.
from operator import mul print reduce(mul,range(21,41))/reduce(mul,range(1,21))
파이썬 만세!
Saturday, April 18, 2015
Project Euler #14 - Longest Collatz sequence
Longest Collatz sequence
13->40->20->10->5->16 ... 이렇게 해서 13:10을 찾았다면, 40:9, 20:8 도 메모리에 저장해 두고, 나중에 20이나 40이 나왔을 때 다시 계산하지 않도록 한다. 이런 식이라면, 이미 10:7이 메모리에 있었을테니, 13에 대해 10번 계산이 아니라 세 번 계산만에 13:10을 찾을 수 있다.
이렇게 하면 4.3초...
그런데, 13:10만 저장하고 40:9, 20:8 을 저장 안 하면 속도가 더 빨라진다. 아래 코드는 2.7초..
tl 이라는 리스트에 값을 하나씩 더하고 다시 꺼내는 데 드는 비용이 cache 비용보다 더 많이 드나보다.
13->40->20->10->5->16 ... 이렇게 해서 13:10을 찾았다면, 40:9, 20:8 도 메모리에 저장해 두고, 나중에 20이나 40이 나왔을 때 다시 계산하지 않도록 한다. 이런 식이라면, 이미 10:7이 메모리에 있었을테니, 13에 대해 10번 계산이 아니라 세 번 계산만에 13:10을 찾을 수 있다.
def collatz(n,cDic): m = n i = 0 tl = [n] while True: if m in cDic: for s, t in enumerate(tl[::-1]): cDic[t] = s + 1 + cDic[m] return if m % 2 == 0: m = m / 2 else: m = 3 * m + 1 tl.append(m) i += 1 cDic = {1:1} for i in range(2,1000000): collatz(i,cDic) print max(cDic, key=cDic.get)
이렇게 하면 4.3초...
그런데, 13:10만 저장하고 40:9, 20:8 을 저장 안 하면 속도가 더 빨라진다. 아래 코드는 2.7초..
tl 이라는 리스트에 값을 하나씩 더하고 다시 꺼내는 데 드는 비용이 cache 비용보다 더 많이 드나보다.
def collatz(n,cDic): m = n i = 0 while True: if m in cDic: cDic[n] = i + cDic[m] return if m % 2 == 0: m = m / 2 else: m = 3 * m + 1 i += 1 cDic = {1:1} for i in range(2,1000000): collatz(i,cDic) print max(cDic, key=cDic.get)
Project Euler #13 - 큰 수의 합
50자리 숫자 100개를 더했을 때 제일 앞자리 숫자 10개는?
파이썬이 큰 정수 다룰 때 얼마나 편한지 보여주는 좋은 예!
---
파이썬에서는 큰 정수를 편하고 안전하게 쓸 수 있다는 점을 다른 곳에 활용할 수도 있다. 예를 들어 sqrt(2)를 소수점 이하 100자리까지 구할 때, float로 다루는 것보다 2*10^200 의 sqrt를 찾는 게 더 쉽다.
파이썬이 큰 정수 다룰 때 얼마나 편한지 보여주는 좋은 예!
st = '''37107287533902102798797998220837590246510135740250 46376937677490009712648124896970078050417018260538 ... 53503534226472524250874054075591789781264330331690''' print str(sum([int(s) for s in st.split()]))[:10]
---
파이썬에서는 큰 정수를 편하고 안전하게 쓸 수 있다는 점을 다른 곳에 활용할 수도 있다. 예를 들어 sqrt(2)를 소수점 이하 100자리까지 구할 때, float로 다루는 것보다 2*10^200 의 sqrt를 찾는 게 더 쉽다.
Project Euler #12 - 500개 이상의 약수를 갖는 최소의 삼각수
"500개 이상의 약수를 갖는 최소의 삼각수" - 우리말로 써 놓기는 했지만 이걸 보고 문제를 이해하기는 어렵겠다.
요렇게 하면 0.6초 걸려서 답이 나온다.
i를 굳이 10에서 시작할 필요는 없다. 10000 정도에서 시작해도 무방.
i*(i+1)/2 로 삼각수를 만들었는데.. 아래가 더 낫다.
하지만 병목은 '삼각수'를 만드는 게 아니라 '소인수 분해'하는 쪽이어서 이렇게 한다고 뭐가 개선되거나 하지는 않는다.
reduce - mul에 대해서는 8번 문제에서 간단히 썼다. reduce를 쓰지 않고 더 짧은 코드로 문제를 풀 수도 있다. sympy에는 약수를 모두 찾아주는 함수(divisors)도 있다. 대신 이렇게 하면 실행 시간이 두배 정도 걸린다. 약수의 개수가 필요한데 약수를 모두 계산하려니 시간이 더 걸리나보다.
더 나은 방법은 sympy를 쓰지 않고 5번에서 만들어 두었던 소인수 분해 함수를 응용하는 것이다. 소인수분해를 하려면 소수(prime numbers)의 리스트가 필요하다. 소인수분해를 할 때마다 이 리스트를 반복해서 만들면 효율이 떨어질 수 밖에 없다. 필요한만큼 넉넉하게 소수를 준비해 두고 소인수분해에서 활용하면 좋은데, sympy의 factorint를 써서는 이게 불가능한 듯 하다. 그럼 직접 만들어 써야지. 아래에서는 10만까지의 소수만 만들었으니, 만약 답이 100억이 넘는다면 소수를 더 만들어서 다시 돌려야 한다. 다행히 답은 1억 아래에서 나왔고 실행 시간은 0.3초 정도로 sympy.factorint를 썼을 때의 절반으로 줄었다.
요렇게 하면 0.6초 걸려서 답이 나온다.
from sympy import factorint from operator import mul i = 10 while True: f = factorint(i*(i+1)/2) if reduce(mul,[f[k]+1 for k in f]) > 500: print i*(i+1)/2 break i += 1
i를 굳이 10에서 시작할 필요는 없다. 10000 정도에서 시작해도 무방.
i*(i+1)/2 로 삼각수를 만들었는데.. 아래가 더 낫다.
i, t = 10, 55 while True: f = factorint(t) if reduce(mul,[f[k]+1 for k in f]) > 500: print i*(i+1)/2 break i += 1 t += i
하지만 병목은 '삼각수'를 만드는 게 아니라 '소인수 분해'하는 쪽이어서 이렇게 한다고 뭐가 개선되거나 하지는 않는다.
reduce - mul에 대해서는 8번 문제에서 간단히 썼다. reduce를 쓰지 않고 더 짧은 코드로 문제를 풀 수도 있다. sympy에는 약수를 모두 찾아주는 함수(divisors)도 있다. 대신 이렇게 하면 실행 시간이 두배 정도 걸린다. 약수의 개수가 필요한데 약수를 모두 계산하려니 시간이 더 걸리나보다.
from sympy import divisors i = 0 while True: if len(divisors(i*(i+1)/2)) > 500: print i*(i+1)/2 break i += 1
더 나은 방법은 sympy를 쓰지 않고 5번에서 만들어 두었던 소인수 분해 함수를 응용하는 것이다. 소인수분해를 하려면 소수(prime numbers)의 리스트가 필요하다. 소인수분해를 할 때마다 이 리스트를 반복해서 만들면 효율이 떨어질 수 밖에 없다. 필요한만큼 넉넉하게 소수를 준비해 두고 소인수분해에서 활용하면 좋은데, sympy의 factorint를 써서는 이게 불가능한 듯 하다. 그럼 직접 만들어 써야지. 아래에서는 10만까지의 소수만 만들었으니, 만약 답이 100억이 넘는다면 소수를 더 만들어서 다시 돌려야 한다. 다행히 답은 1억 아래에서 나왔고 실행 시간은 0.3초 정도로 sympy.factorint를 썼을 때의 절반으로 줄었다.
from operator import mul def rwh_primes1(n): # http://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188 """ Returns a list of primes < n """ sieve = [True] * (n/2) for i in xrange(3,int(n**0.5)+1,2): if sieve[i/2]: sieve[i*i/2::i] = [False] * ((n-i*i-1)/(2*i)+1) return [2] + [2*i+1 for i in xrange(1,n/2) if sieve[i]] def ndiv(n,pn): # n > 2 i, fDic = 0, {} while True: p = pn[i] if n % p == 0: if p in fDic: fDic[p] += 1 else: fDic[p] = 1 n /= p i -= 1 i += 1 if pn[i]**2 > n and n > 1: if n in fDic: fDic[n] += 1 else: fDic[n] = 1 return reduce(mul,[x+1 for x in list(fDic.values())]) pn = rwh_primes1(100000) tn, lasttn = 1, 2 while True: tn += lasttn if ndiv(tn,pn) > 500: print tn break lasttn += 1
Subscribe to:
Posts (Atom)