def min_divisors_sum(n): """min(d1 + d2 + ... + dk - k | d1 * d2 * ... * dk == n)""" if n not in min_divisors_sum_save: s = 0 for p, k in factorize(n).iteritems(): s += (p - 1) * k min_divisors_sum_save[n] = s return min_divisors_sum_save[n]
def num_factors(n, a, b, c, d): #print n, (a, b, c, d), (2 ** a * 5 ** b , 2 ** c * 5 ** d) f = factorize(2 ** a * 5 ** b + 2 ** c * 5 ** d) #print 2 ** a * 5 ** b + 2 ** c + 5 ** d, f f[2] = (f[2] if f.has_key(2) else 0) + n - a - c f[5] = (f[5] if f.has_key(5) else 0) + n - b - d #print f return prod([v + 1 for v in f.itervalues()])
def factors(n, P): # assuming n > 1 '''Return set of factors of n that are co-prime with 2 and 5. P = prime list to use for factorization.''' # print 'n', n d = factorize(n, P) d_filtered = [(k, v) for k, v in d.iteritems() if k != 2 and k != 5] if d else [] if not d_filtered: return set([1, n] if n != 2 and n != 5 else [1]) keys, values, m = [f[0] for f in d_filtered], [f[1] for f in d_filtered], len(d_filtered) # print 'n', n, 'd', d, d_filtered, keys, values, 'm', m # print list(it.product(*(xrange(v + 1) for v in values))) return set([np.prod([keys[i] ** combo[i] for i in xrange(m)]) for combo in it.product(*(xrange(v + 1) for v in values))])
def sum_4p3(n): """Sum of all the numbers <= n with prime divs 2, 4k + 3.""" if n >= len(sum_4p3_save): for k in range(len(sum_4p3_save), n + 1): no_4k1 = True for p, _ in factorize(k).iteritems(): if p % 4 == 1: no_4k1 = False break if no_4k1: sum_4p3_save.append(sum_4p3_save[-1] + k) else: sum_4p3_save.append(sum_4p3_save[-1]) return sum_4p3_save[n]
def first_in_seq(L, limit=None): '''Will run indefinitely if a sequence of size L does not exist.''' y = 1 for x in (it.count(2) if limit is None else xrange(2, limit + 1)): if x % 10000 == 0: print x # if is_not_admissible(x, L): if len(set(factorize(x).keys())) != L: y = x if x - y == L: # L consecutive successes return y + 1 return None
def divisors(n): f = factorize(n).items() d = 1 p = [0] * len(f) while True: yield d i = 0 while i < len(f) and p[i] == f[i][1]: p[i] = 0 d //= f[i][0] ** f[i][1] i += 1 if i >= len(f): break p[i] += 1 d *= f[i][0]
def min_n_above(S): s = 2 * S + 1 m = int(ceil(log(s) / log(3))) p = primes('first', m) fac, n, f = dict((x, factorize(x)) for x in xrange(1, p[-1])), prod([long(x) for x in p]), dict((x, 1) for x in p) while p.size: found, f0 = False, f.copy() del f0[p[-1]] for t in xrange(1, p[-1]): ft = f0.copy() for k, v in fac[t].iteritems(): ft[k] += v if prod([2 * k + 1 for k in ft.itervalues()]) > s: found, n, f, p = True, (n / p[-1]) * t, ft, p[:-1] break if not found: break return n
def prog_sq(N): '''Return the set of progressive perfect squares <= N.''' result = set([]) for q in xrange(2, int((N / 2.) ** (2. / 3.)) + 1): factors, Q = factorize(q), q * q * q P, c_max = map(long, factors.keys()), min(int(Q ** 0.5), q) # print 'q', q, 'q^3', Q, factors, 'c_max', c_max for K in product(*(xrange(3 * k + 1) for k in factors.itervalues())): c = prod([p ** k for p, k in zip(P, K)]) if c <= c_max: # print '\t', c, Q / c a2 = c + Q / c if a2 <= N and is_int(a2 ** 0.5): # print 'Found', 'q', q, 'q^3', Q, 'c', c, 'd', Q / c, 'n', a2, ' =', int(a2 ** 0.5), '^ 2' d = (a2 - c) / q print 'Found', 'n', a2, ' =', int(a2 ** 0.5), '^ 2 =', 'q', q, 'd', d, 'r', c, 'd**0.5', d ** 0.5, '(d/2)**0.5', (d / 2.) ** 0.5 result.add(a2) return result
def min_n(S): '''Brute-force, not terribly efficient. See Problem 110 for a better method.''' s = 2 * S + 1 return dropwhile(prod(lambda n: prod([2 * k + 1 for k in factorize(n).itervalues()]) <= s), count(2)).next()
''' ============================================================ http://projecteuler.net/problem=187 A composite is a number containing at least two prime factors. For example, 15 = 3 5; 9 = 3 3; 12 = 2 2 3. There are ten composites below thirty containing precisely two, not necessarily distinct, prime factors: 4, 6, 9, 10, 14, 15, 21, 22, 25, 26. How many composite integers, n 108, have precisely two, not necessarily distinct, prime factors? ============================================================ ''' from problem007 import primes from itertools import takewhile from math import ceil from problem012 import factorize def num_comp2(N): p_limit = int(ceil(N - 1) ** 0.5) P = primes('lt', int(ceil(N - 1) * 0.5) + 1) # Sorted ascending return sum(sum(1 for _ in takewhile(lambda q: q <= q_limit, P[k:])) for (k, q_limit) in ((k, N / p) for k, p in enumerate(takewhile(lambda p: p <= p_limit, P)))) num_comp2_bf = lambda N: sum(1 for (_, f) in ((n, factorize(n)) for n in xrange(2, N)) # @UnusedVariable if (len(f) == 2 and f.values() == [1, 1]) or (len(f) == 1 and f.values() == [2])) if __name__ == "__main__": print num_comp2(10 ** 8)
def sum_roots_of_unity(n, k): '''Sum of all kth-order roots of unit of n using the Chinese Remainder Theorem.''' f = map(int, [p ** l for p, l in factorize(n).iteritems()]) return sum(crt(zip(r, f)) for r in product(*(filter(lambda x: pow(x, k, p) == 1, xrange(1, p)) for p in f)))
def other_factor(k, factors): '''Does k have other primes factors than the list ''factors''?''' i, l = 0, len(factors) while i < l and k > 1: if k % factors[i] == 0: k /= factors[i] else: i += 1 return k > 1 def sum_using_other_factor(max_prime): s = 0 for p in islice(primes('lt', max_prime), 3, 100000000): a = A(p) other_fac = other_factor(a, ten_factors) if other_fac: s += p print p, a, other_fac, s return s + 10 # 10=2+3+5 = boundary case def sum_using_max_n(max_prime, n=16): k = 10 ** n return sum(p for p in primes('lt', max_prime) if pow(10, k, int(9 * p)) != 1) sum_mine = lambda max_prime: 10 + sum(p for (p, _) in ifilter(lambda (_, a): not (factorize(a).keys() <= ten_factors), ((p, A(p)) for p in primes('lt', max_prime) if p != 2 and p != 5))) if __name__ == "__main__": N = 10 ** 5 print sum_using_max_n(N) print sum_using_other_factor(N) print sum_mine(N)
from problem007 import primes from itertools import takewhile from problem012 import factorize '''A dynamic programming solution.''' class HammingCounter(object): def __init__(self, max_k): self.h, self.p = {}, primes('lt', max_k + 1) def H_of_prime(self, n, k): return self.H(n, sum(1 for _ in takewhile(lambda p:p <= k, self.p)) - 1) def H(self, n, k): return self.h.setdefault((n, k), self._H(n, k)) def _H(self, n, k): if n == 1 or k < 0: return 1 h, km, p = 0, k - 1, self.p[k] while n: h += self.H(n, km) n /= p return h num_hamming = lambda n, k: HammingCounter(k).H_of_prime(n, k) '''Brute-force counting.''' num_hamming_bf = lambda n, k: sum(1 for x in xrange(2, n + 1) if max(factorize(x).iterkeys()) <= k) + 1 hamming_bf = lambda n, k: [1] + [x for x in xrange(2, n + 1) if max(factorize(x).iterkeys()) <= k] if __name__ == "__main__": print hamming_bf(15, 5) print num_hamming(15, 5), num_hamming_bf(15, 5) print num_hamming(10000, 100), num_hamming_bf(10000, 100) print num_hamming(10 ** 8, 5) print num_hamming(10 ** 9, 100) print num_hamming(10 ** 10, 100)