def ffffv1v2(N): "f*****g fast factorial factoring -- edit" rt = int(math.sqrt(N)) prms = [True]*(N+1) prms = sieve(N) bits = [N//k for k in range(1, int(math.sqrt(N))+1)] #<-- actual buckets #bits.reverse() #print(bits) #buckets = {} d = {} for k in range(len(bits)-1): #NB: only goes up to sqrt(N)-1 #print("(%d, %d]" % bounds) for i in range(bits[k+1]+1, bits[k]+1): if prms[i]: d[i] = k+1 #buckets[k+1] = [i for i in if prms[i]] #print(buckets) def c(b): "count the number of powers of b in N!" m = int(math.log(N, b)) return sum(N//b**j for j in range(1, m+1)) for i in range(2, int(math.sqrt(N))+1): if prms[i]: d[i] = c(i) #for k in buckets: # for e in buckets[k]: # d[e] = k return d
def ffffv4(N): S = sieve(N) factorization = {} #important f*****g line: #also, magical f*****g line. #k is a bucket index, (N//(k+1), N//k] is a bucket interval for bucket k. but many buckets are lamely empty, #however these lines compute *only* the nonempty buckets bits = [N//k for k in range(1, int(math.sqrt(N)))] #<-- actual buckets bits += [g for g in range(bits[-1]-1, 0, -1)] #<-- single elements bits.reverse() #print(bits) for i,k in enumerate(bits[:-1]): Range = bits[-(i+1)-1]+1, bits[-(i+1)]+1 #print(i, k, Range) #block = S[Range[0]:Range[1]] #print("=>", block) for i in range(*Range): p = i #S[i] #[p for p in block if p > 0]: if not S[p]: continue #if k < math.sqrt(N): # print(i,p) factorization[p] = factorization.get(p, 0) + k #print(prettyprint(factorization)) def c(b): "count the number of powers of b in N!" m = int(math.log(N, b)) return sum(N//b**j for j in range(2, m+1)) i = 0 for i in range(2, int(math.sqrt(N))+1): if S[i]: factorization[i] += c(i) #prms = [i for i in range(2, int(math.sqrt(N))+1) if prms[i]] #print(prettyprint(factorization)) return factorization