def test_integer_nth_root(self): self.assertRaisesRegexp(ValueError, "integer_nth_root: Must have n >= 1", integer_nth_root, 0, 10) self.assertRaisesRegexp(ValueError, "integer_nth_root: Must have m >= 0", integer_nth_root, 3, -1) self.assertEqual(integer_nth_root(1, 10), 10) self.assertEqual(integer_nth_root(3, 1), 1) for i in xrange(100): a = random.randint(100, 1000) b = random.randint(100, 1000) m = a**b n = random.randint(2, 200) r = integer_nth_root(n, m) self.assertTrue(r**n <= m < (r + 1)**n)
def lehman(n): """ Returns a nontrivial divisor of n, or proves primality. Given an integer n > 1, this algorithm finds a nontrivial factor of n if n is not prime, or returns n if n is prime. Input: * n: int (n >= 3) Output: * d: int If d == n, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Examples: >>> l = 1112470797641561909 >>> lehman(l) 1056689261L Details: The algorithm used is Lehman's Method. This algorithm runs in time O(n^(1/3)), where n is the number to be factored / proven prime. This is substantially better than O(n^(1/2)) trial division for reasonably small value of n, but this algorithm is not suited for large values of n. See section 8.4 of "A Course in Computational Algebraic Number Theory" by Cohen or section 5.1.2 of "Prime Numbers - A Computational Perspective" by Crandall and Pomerance for more details. """ # first, we trial divide up to floor(n^(1/3)) bound = integer_nth_root(3, n) d = trial_division(n, bound) if d < n: return d for k in xrange(1, bound + 1): if k % 2 == 0: r = 1 m = 2 else: r = k + n m = 4 # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2 # and a = r (mod m) fkn = 4*k*n a = integer_sqrt(fkn) # now, increase a until a = r (mod m) rm = r % m while a % m != rm: a += 1 ub = fkn + bound**2 while fkn <= a*a <= ub: c = a*a - fkn b = integer_sqrt(c) if b*b == c: return gcd(a + b, n) a += m return n
def is_power2(n): k = 2 while 2**k <= n: r = integer_nth_root(k, n) if r**k == n: return (r, k) k += 1 return False
def meissel(n): if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_nth_root(3, n**2) primes, pi_cache = pi_table(root) a = pi_cache[integer_nth_root(3, n)] b = pi_cache[integer_nth_root(2, n)] def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] b = pi_cache[int((x + 0.5)**(0.5))] c = pi_cache[int((x + 0.5)**(1.0 / 3.0))] if a <= 7: if a == 1: value = x - x // 2 elif a == 2: value = x - x // 2 - x // 3 + x // 6 elif a == 3: value = x - x // 2 - x // 3 - x // 5 + x // 6 + x // 10 + x // 15 - x // 30 elif a == 4: value = (x - x // 2 - x // 3 - x // 5 - x // 7 + x // 6 + x // 10 + x // 14 + x // 15 + x // 21 + x // 35 - x // 30 - x // 42 - x // 70 - x // 105 + x // 210) elif a == 5: value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 + x // 6 + x // 10 + x // 14 + x // 22 + x // 15 + x // 21 + x // 33 + x // 35 + x // 55 + x // 77 - x // 30 - x // 42 - x // 66 - x // 70 - x // 110 - x // 154 - x // 105 - x // 165 - x // 231 - x // 385 + x // 210 + x // 330 + x // 462 + x // 770 + x // 1155 - x // 2310) elif a == 6: value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 + x // 15 + x // 21 + x // 33 + x // 39 + x // 35 + x // 55 + x // 65 + x // 77 + x // 91 + x // 143 - x // 30 - x // 42 - x // 66 - x // 78 - x // 70 - x // 110 - x // 130 - x // 154 - x // 182 - x // 286 - x // 105 - x // 165 - x // 195 - x // 231 - x // 273 - x // 429 - x // 385 - x // 455 - x // 715 - x // 1001 + x // 210 + x // 330 + x // 390 + x // 462 + x // 546 + x // 858 + x // 770 + x // 910 + x // 1430 + x // 2002 + x // 1155 + x // 1365 + x // 2145 + x // 3003 + x // 5005 - x // 2310 - x // 2730 - x // 4290 - x // 6006 - x // 10010 - x // 15015 + x // 30030) else: value = ( x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 - x // 17 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 + x // 34 + x // 15 + x // 21 + x // 33 + x // 39 + x // 51 + x // 35 + x // 55 + x // 65 + x // 85 + x // 77 + x // 91 + x // 119 + x // 143 + x // 187 + x // 221 - x // 30 - x // 42 - x // 66 - x // 78 - x // 102 - x // 70 - x // 110 - x // 130 - x // 170 - x // 154 - x // 182 - x // 238 - x // 286 - x // 374 - x // 442 - x // 105 - x // 165 - x // 195 - x // 255 - x // 231 - x // 273 - x // 357 - x // 429 - x // 561 - x // 663 - x // 385 - x // 455 - x // 595 - x // 715 - x // 935 - x // 1105 - x // 1001 - x // 1309 - x // 1547 - x // 2431 + x // 210 + x // 330 + x // 390 + x // 510 + x // 462 + x // 546 + x // 714 + x // 858 + x // 1122 + x // 1326 + x // 770 + x // 910 + x // 1190 + x // 1430 + x // 1870 + x // 2210 + x // 2002 + x // 2618 + x // 3094 + x // 4862 + x // 1155 + x // 1365 + x // 1785 + x // 2145 + x // 2805 + x // 3315 + x // 3003 + x // 3927 + x // 4641 + x // 7293 + x // 5005 + x // 6545 + x // 7735 + x // 12155 + x // 17017 - x // 2310 - x // 2730 - x // 3570 - x // 4290 - x // 5610 - x // 6630 - x // 6006 - x // 7854 - x // 9282 - x // 14586 - x // 10010 - x // 13090 - x // 15470 - x // 24310 - x // 34034 - x // 15015 - x // 19635 - x // 23205 - x // 36465 - x // 51051 - x // 85085 + x // 30030 + x // 39270 + x // 46410 + x // 72930 + x // 102102 + x // 170170 + x // 255255 - x // 510510) elif b > a >= c and x <= root: value = pi_cache[x] - a + 1 + phi2(x, a, b) elif a >= b and x <= root: value = pi_cache[x] - a + 1 else: value = (x + 1) // 2 for i in xrange(1, a): if primes[i] > x: break value -= phi(x // primes[i], i) cache[x, a] = value return value def phi2(n, a, b): total = (a - b) * (b + a - 1) // 2 for i in xrange(a, b): total += pi_cache[n // primes[i]] return total value = phi(n, a) - 1 + a - phi2(n, a, b) return value
def lmo(x): if x <= 1: return 0 elif x <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, x) root = integer_nth_root(3, x**2) primes = sieves.primes(root) t = integer_nth_root(3, x) c = bisect(primes, t) b = bisect(primes, integer_nth_root(2, x)) value = (b + c - 2) * (b - c + 1) // 2 for i in xrange(c, b): idx = bisect(primes, x // primes[i]) value -= idx special = defaultdict(list) stack = [(1, c, 1)] push = stack.append pop = stack.pop # print "recursing" while stack: (n, a, sign) = pop() if a == 1 and n <= t: if sign > 0: value += (x // n + 1) // 2 else: value -= (x // n + 1) // 2 elif n > t: special[a].append((x // n, sign)) else: push((n, a - 1, sign)) push((n * primes[a - 1], a - 1, -sign)) block = [1] * (root + 1) block[0] = 0 for a in sorted(special): p = primes[a - 1] block[p::p] = [0] * (root // p) last_v = 0 last_s = 0 for v, sign in sorted(special[a]): last_s += sum(block[last_v:v + 1]) last_v = v + 1 if sign > 0: value += last_s else: value -= last_s return value
def lehmer(n): if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_nth_root(4, n**3) primes = sieves.primes(root) a = bisect(primes, integer_nth_root(4, n)) b = bisect(primes, integer_sqrt(n)) c = bisect(primes, integer_nth_root(3, n)) def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if a <= 7: if a == 1: value = x - x // 2 elif a == 2: value = x - x // 2 - x // 3 + x // 6 elif a == 3: value = x - x // 2 - x // 3 - x // 5 + x // 6 + x // 10 + x // 15 - x // 30 elif a == 4: value = (x - x // 2 - x // 3 - x // 5 - x // 7 + x // 6 + x // 10 + x // 14 + x // 15 + x // 21 + x // 35 - x // 30 - x // 42 - x // 70 - x // 105 + x // 210) elif a == 5: value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 + x // 6 + x // 10 + x // 14 + x // 22 + x // 15 + x // 21 + x // 33 + x // 35 + x // 55 + x // 77 - x // 30 - x // 42 - x // 66 - x // 70 - x // 110 - x // 154 - x // 105 - x // 165 - x // 231 - x // 385 + x // 210 + x // 330 + x // 462 + x // 770 + x // 1155 - x // 2310) elif a == 6: value = (x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 + x // 15 + x // 21 + x // 33 + x // 39 + x // 35 + x // 55 + x // 65 + x // 77 + x // 91 + x // 143 - x // 30 - x // 42 - x // 66 - x // 78 - x // 70 - x // 110 - x // 130 - x // 154 - x // 182 - x // 286 - x // 105 - x // 165 - x // 195 - x // 231 - x // 273 - x // 429 - x // 385 - x // 455 - x // 715 - x // 1001 + x // 210 + x // 330 + x // 390 + x // 462 + x // 546 + x // 858 + x // 770 + x // 910 + x // 1430 + x // 2002 + x // 1155 + x // 1365 + x // 2145 + x // 3003 + x // 5005 - x // 2310 - x // 2730 - x // 4290 - x // 6006 - x // 10010 - x // 15015 + x // 30030) else: value = ( x - x // 2 - x // 3 - x // 5 - x // 7 - x // 11 - x // 13 - x // 17 + x // 6 + x // 10 + x // 14 + x // 22 + x // 26 + x // 34 + x // 15 + x // 21 + x // 33 + x // 39 + x // 51 + x // 35 + x // 55 + x // 65 + x // 85 + x // 77 + x // 91 + x // 119 + x // 143 + x // 187 + x // 221 - x // 30 - x // 42 - x // 66 - x // 78 - x // 102 - x // 70 - x // 110 - x // 130 - x // 170 - x // 154 - x // 182 - x // 238 - x // 286 - x // 374 - x // 442 - x // 105 - x // 165 - x // 195 - x // 255 - x // 231 - x // 273 - x // 357 - x // 429 - x // 561 - x // 663 - x // 385 - x // 455 - x // 595 - x // 715 - x // 935 - x // 1105 - x // 1001 - x // 1309 - x // 1547 - x // 2431 + x // 210 + x // 330 + x // 390 + x // 510 + x // 462 + x // 546 + x // 714 + x // 858 + x // 1122 + x // 1326 + x // 770 + x // 910 + x // 1190 + x // 1430 + x // 1870 + x // 2210 + x // 2002 + x // 2618 + x // 3094 + x // 4862 + x // 1155 + x // 1365 + x // 1785 + x // 2145 + x // 2805 + x // 3315 + x // 3003 + x // 3927 + x // 4641 + x // 7293 + x // 5005 + x // 6545 + x // 7735 + x // 12155 + x // 17017 - x // 2310 - x // 2730 - x // 3570 - x // 4290 - x // 5610 - x // 6630 - x // 6006 - x // 7854 - x // 9282 - x // 14586 - x // 10010 - x // 13090 - x // 15470 - x // 24310 - x // 34034 - x // 15015 - x // 19635 - x // 23205 - x // 36465 - x // 51051 - x // 85085 + x // 30030 + x // 39270 + x // 46410 + x // 72930 + x // 102102 + x // 170170 + x // 255255 - x // 510510) elif a >= bisect(primes, x**(0.5)) and x < primes[-1]: pi = bisect(primes, x) value = pi - a + 1 else: value = (x + 1) // 2 for i in xrange(1, a): if primes[i] > x: break value -= phi(x // primes[i], i) cache[x, a] = value return value def phi2(n, a, b): s1 = 0 for i in xrange(a, b): s1 += phi(n // primes[i], b) + b - 1 return s1 def phi3(n, a, b, c): s2 = 0 for i in xrange(a, c): bi = phi(integer_sqrt(n // primes[i]), b) + b - 1 for j in xrange(i, bi): idx = phi(n // (primes[i] * primes[j]), b) + b - 1 s2 += idx - j return s2 value = (b + a - 2) * (b - a + 1) // 2 + phi(n, a) - phi2(n, a, b) - phi3( n, a, b, c) return value
def is_power(n, k=None, detect_only=False): """Determines if n is a perfect power. If n is a perfect power, this returns (b, k) where n = b^k with k maximal. If the optional parameter k is given, this returns (b, k) if n = b^k for some b. Otherwise, returns False. Input: * n: int or list (n >= 1) The value of n can be an int or a factorization. * k: int (k >= 1) (default=None) Returns: * (b, k): tuple of ints Values such that n = b^k if such values exist. * Returns False if no such values exist. Raises: * ValueError: If n <= 0 or k <= 0. Examples: >>> is_power(36) (6, 2) >>> is_power(81) (3, 4) >>> is_power(81, 2) (9, 2) >>> is_power(1330) False >>> is_power([(2, 4), (5, 4)]) (10, 4) >>> is_power([(2, 4), (5, 4)], 2) (100, 2) >>> is_power([(2, 3), (5, 2)]) False >>> is_power(17, 0) Traceback (most recent call last): ... ValueError: is_power: Must have k >= 1. >>> is_power(0) Traceback (most recent call last): ... ValueError: is_power: Must have n >= 1. Details: If n is given as an int and a value of k is given, then this function computes the integer kth root r of n and checks if r^k = n. In the case where no such k is given, this looks at each k >= 2, extracts the integer kth root of n, and uses this to determine if n is a kth power. If n is given as a factorization and a value of k is given, this function checks if each exponent in the prime factorization of n is divisible by k. If no such k is given, this computes the gcd d of the exponents in the prime factorization and checks if d > 1. """ if k is not None and k < 1: raise ValueError("is_power: Must have k >= 1.") if isinstance(n, list): if n[0][0] == -1: raise ValueError("is_power: Must have n >= 1.") n_factorization = n[:] kth_root = 1 if k is not None: for (p, e) in n_factorization: if e % k == 0: kth_root *= p**(e // k) else: return False return (kth_root, k) else: exponents = [e for (p, e) in n_factorization] d = gcd_list(exponents) if d == 1: return False else: kth_root = 1 for (p, e) in n_factorization: kth_root *= p**(e // d) return (kth_root, d) else: if n < 1: raise ValueError("is_power: Must have n >= 1.") if k is not None: if k == 1: return (n, 1) root = integer_nth_root(k, n) if root**k == n: return (root, k) return False for k in xrange(2, n.bit_length() + 1): base = integer_nth_root(k, n) if base**k == n: exponent = k while True: next_step = is_power(base) if next_step: base = next_step[0] exponent *= next_step[1] else: return (base, exponent) return False
def lehman(n): r"""Returns a nontrivial divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` using Lehman's method. Parameters ---------- n : int (n > 1) Returns ------- d : int If d == n, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Notes ----- This algorithm runs in time O(n^(1/3)). This is substantially better than O(n^(1/2)) trial division for reasonably small value of n, but this algorithm is not suited for large values of n. See section 8.4 of [1] or section 5.1.2 of [2] for more details. References ---------- .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory", Springer-Verlag, New York, 2000. .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. Examples -------- >>> lehman(100) 2 >>> lehman(1112470797641561909) 1056689261L """ # first, we trial divide up to floor(n^(1/3)) bound = integer_nth_root(3, n) d = trial_division(n, bound) if d < n: return d for k in xrange(1, bound + 1): if k % 2 == 0: r = 1 m = 2 else: r = k + n m = 4 # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2 # and a = r (mod m) fkn = 4 * k * n a = integer_sqrt(fkn) # now, increase a until a = r (mod m) rm = r % m while a % m != rm: a += 1 ub = fkn + bound**2 while fkn <= a * a <= ub: c = a * a - fkn b = integer_sqrt(c) if b * b == c: return gcd(a + b, n) a += m return n
def meissel(n): if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_nth_root(3, n**2) primes, pi_cache = pi_table(root) a = pi_cache[integer_nth_root(3, n)] b = pi_cache[integer_nth_root(2, n)] def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] b = pi_cache[int((x + 0.5)**(0.5))] c = pi_cache[int((x + 0.5)**(1.0/3.0))] if a <= 7: if a == 1: value = x - x//2 elif a == 2: value = x - x//2 - x//3 + x//6 elif a == 3: value = x - x//2 - x//3 - x//5 + x//6 + x//10 + x//15 - x//30 elif a == 4: value = (x - x//2 - x//3 - x//5 - x//7 + x//6 + x//10 + x//14 + x//15 + x//21 + x//35 - x//30 - x//42 - x//70 - x//105 + x//210) elif a == 5: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 + x//6 + x//10 + x//14 + x//22 + x//15 + x//21 + x//33 + x//35 + x//55 + x//77 - x//30 - x//42 - x//66 - x//70 - x//110 - x//154 - x//105 - x//165 - x//231 - x//385 + x//210 + x//330 + x//462 + x//770 + x//1155 - x//2310) elif a == 6: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 + x//6 + x//10 + x//14 + x//22 + x//26 + x//15 + x//21 + x//33 + x//39 + x//35 + x//55 + x//65 + x//77 + x//91 + x//143 - x//30 - x//42 - x//66 - x//78 - x//70 - x//110 - x//130 - x//154 - x//182 - x//286 - x//105 - x//165 - x//195 - x//231 - x//273 - x//429 - x//385 - x//455 - x//715 - x//1001 + x//210 + x//330 + x//390 + x//462 + x//546 + x//858 + x//770 + x//910 + x//1430 + x//2002 + x//1155 + x//1365 + x//2145 + x//3003 + x//5005 - x//2310 - x//2730 - x//4290 - x//6006 - x//10010 - x//15015 + x//30030) else: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 - x//17 + x//6 + x//10 + x//14 + x//22 + x//26 + x//34 + x//15 + x//21 + x//33 + x//39 + x//51 + x//35 + x//55 + x//65 + x//85 + x//77 + x//91 + x//119 + x//143 + x//187 + x//221 - x//30 - x//42 - x//66 - x//78 - x//102 - x//70 - x//110 - x//130 - x//170 - x//154 - x//182 - x//238 - x//286 - x//374 - x//442 - x//105 - x//165 - x//195 - x//255 - x//231 - x//273 - x//357 - x//429 - x//561 - x//663 - x//385 - x//455 - x//595 - x//715 - x//935 - x//1105 - x//1001 - x//1309 - x//1547 - x//2431 + x//210 + x//330 + x//390 + x//510 + x//462 + x//546 + x//714 + x//858 + x//1122 + x//1326 + x//770 + x//910 + x//1190 + x//1430 + x//1870 + x//2210 + x//2002 + x//2618 + x//3094 + x//4862 + x//1155 + x//1365 + x//1785 + x//2145 + x//2805 + x//3315 + x//3003 + x//3927 + x//4641 + x//7293 + x//5005 + x//6545 + x//7735 + x//12155 + x//17017 - x//2310 - x//2730 - x//3570 - x//4290 - x//5610 - x//6630 - x//6006 - x//7854 - x//9282 - x//14586 - x//10010 - x//13090 - x//15470 - x//24310 - x//34034 - x//15015 - x//19635 - x//23205 - x//36465 - x//51051 - x//85085 + x//30030 + x//39270 + x//46410 + x//72930 + x//102102 + x//170170 + x//255255 - x//510510) elif b > a >= c and x <= root: value = pi_cache[x] - a + 1 + phi2(x, a, b) elif a >= b and x <= root: value = pi_cache[x] - a + 1 else: value = (x + 1)//2 for i in xrange(1, a): if primes[i] > x: break value -= phi(x//primes[i], i) cache[x, a] = value return value def phi2(n, a, b): total = (a - b)*(b + a - 1)//2 for i in xrange(a, b): total += pi_cache[n//primes[i]] return total value = phi(n, a) - 1 + a - phi2(n, a, b) return value
def lmo(x): if x <= 1: return 0 elif x <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, x) root = integer_nth_root(3, x**2) primes = rosemary.number_theory.sieves.primes(root) t = integer_nth_root(3, x) c = bisect(primes, t) b = bisect(primes, integer_nth_root(2, x)) value = (b + c - 2)*(b - c + 1)//2 for i in xrange(c, b): idx = bisect(primes, x//primes[i]) value -= idx special = defaultdict(list) stack = [(1, c, 1)] push = stack.append pop = stack.pop # print "recursing" while stack: (n, a, sign) = pop() if a == 1 and n <= t: if sign > 0: value += (x//n + 1)//2 else: value -= (x//n + 1)//2 elif n > t: special[a].append((x//n, sign)) else: push((n, a - 1, sign)) push((n*primes[a - 1], a - 1, -sign)) block = [1]*(root + 1) block[0] = 0 for a in sorted(special): p = primes[a - 1] block[p::p] = [0]*(root//p) last_v = 0 last_s = 0 for v, sign in sorted(special[a]): last_s += sum(block[last_v:v + 1]) last_v = v + 1 if sign > 0: value += last_s else: value -= last_s return value
def lehmer(n): if n <= 1: return 0 elif n <= _PRIME_LIST[-1]: return bisect(_PRIME_LIST, n) root = integer_nth_root(4, n**3) primes = rosemary.number_theory.sieves.primes(root) a = bisect(primes, integer_nth_root(4, n)) b = bisect(primes, integer_sqrt(n)) c = bisect(primes, integer_nth_root(3, n)) def phi(x, a, cache={}): if (x, a) in cache: return cache[x, a] if a <= 7: if a == 1: value = x - x//2 elif a == 2: value = x - x//2 - x//3 + x//6 elif a == 3: value = x - x//2 - x//3 - x//5 + x//6 + x//10 + x//15 - x//30 elif a == 4: value = (x - x//2 - x//3 - x//5 - x//7 + x//6 + x//10 + x//14 + x//15 + x//21 + x//35 - x//30 - x//42 - x//70 - x//105 + x//210) elif a == 5: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 + x//6 + x//10 + x//14 + x//22 + x//15 + x//21 + x//33 + x//35 + x//55 + x//77 - x//30 - x//42 - x//66 - x//70 - x//110 - x//154 - x//105 - x//165 - x//231 - x//385 + x//210 + x//330 + x//462 + x//770 + x//1155 - x//2310) elif a == 6: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 + x//6 + x//10 + x//14 + x//22 + x//26 + x//15 + x//21 + x//33 + x//39 + x//35 + x//55 + x//65 + x//77 + x//91 + x//143 - x//30 - x//42 - x//66 - x//78 - x//70 - x//110 - x//130 - x//154 - x//182 - x//286 - x//105 - x//165 - x//195 - x//231 - x//273 - x//429 - x//385 - x//455 - x//715 - x//1001 + x//210 + x//330 + x//390 + x//462 + x//546 + x//858 + x//770 + x//910 + x//1430 + x//2002 + x//1155 + x//1365 + x//2145 + x//3003 + x//5005 - x//2310 - x//2730 - x//4290 - x//6006 - x//10010 - x//15015 + x//30030) else: value = (x - x//2 - x//3 - x//5 - x//7 - x//11 - x//13 - x//17 + x//6 + x//10 + x//14 + x//22 + x//26 + x//34 + x//15 + x//21 + x//33 + x//39 + x//51 + x//35 + x//55 + x//65 + x//85 + x//77 + x//91 + x//119 + x//143 + x//187 + x//221 - x//30 - x//42 - x//66 - x//78 - x//102 - x//70 - x//110 - x//130 - x//170 - x//154 - x//182 - x//238 - x//286 - x//374 - x//442 - x//105 - x//165 - x//195 - x//255 - x//231 - x//273 - x//357 - x//429 - x//561 - x//663 - x//385 - x//455 - x//595 - x//715 - x//935 - x//1105 - x//1001 - x//1309 - x//1547 - x//2431 + x//210 + x//330 + x//390 + x//510 + x//462 + x//546 + x//714 + x//858 + x//1122 + x//1326 + x//770 + x//910 + x//1190 + x//1430 + x//1870 + x//2210 + x//2002 + x//2618 + x//3094 + x//4862 + x//1155 + x//1365 + x//1785 + x//2145 + x//2805 + x//3315 + x//3003 + x//3927 + x//4641 + x//7293 + x//5005 + x//6545 + x//7735 + x//12155 + x//17017 - x//2310 - x//2730 - x//3570 - x//4290 - x//5610 - x//6630 - x//6006 - x//7854 - x//9282 - x//14586 - x//10010 - x//13090 - x//15470 - x//24310 - x//34034 - x//15015 - x//19635 - x//23205 - x//36465 - x//51051 - x//85085 + x//30030 + x//39270 + x//46410 + x//72930 + x//102102 + x//170170 + x//255255 - x//510510) elif a >= bisect(primes, x**(0.5)) and x < primes[-1]: pi = bisect(primes, x) value = pi - a + 1 else: value = (x + 1)//2 for i in xrange(1, a): if primes[i] > x: break value -= phi(x//primes[i], i) cache[x, a] = value return value def phi2(n, a, b): s1 = 0 for i in xrange(a, b): s1 += phi(n//primes[i], b) + b - 1 return s1 def phi3(n, a, b, c): s2 = 0 for i in xrange(a, c): bi = phi(integer_sqrt(n//primes[i]), b) + b - 1 for j in xrange(i, bi): idx = phi(n//(primes[i]*primes[j]), b) + b - 1 s2 += idx - j return s2 value = (b + a - 2)*(b - a + 1)//2 + phi(n, a) - phi2(n, a, b) - phi3(n, a, b, c) return value
def lehman(n): r"""Returns a nontrivial divisor of `n`, or proves primality. Given an integer `n` > 1, this algorithm attempts to find a factor of `n` using Lehman's method. Parameters ---------- n : int (n > 1) Returns ------- d : int If d == n, then n is proven prime. Otherwise, d is a nontrivial divisor of n. Notes ----- This algorithm runs in time O(n^(1/3)). This is substantially better than O(n^(1/2)) trial division for reasonably small value of n, but this algorithm is not suited for large values of n. See section 8.4 of [1] or section 5.1.2 of [2] for more details. References ---------- .. [1] H. Cohen, "A Course in Computational Algebraic Number Theory", Springer-Verlag, New York, 2000. .. [2] R. Crandall, C. Pomerance, "Prime Numbers: A Computational Perspective", Springer-Verlag, New York, 2001. Examples -------- >>> lehman(100) 2 >>> lehman(1112470797641561909) 1056689261L """ # first, we trial divide up to floor(n^(1/3)) bound = integer_nth_root(3, n) d = trial_division(n, bound) if d < n: return d for k in xrange(1, bound + 1): if k % 2 == 0: r = 1 m = 2 else: r = k + n m = 4 # we want to iterate over a, where 4*k*n <= a^2 <= 4*k*n + bound^2 # and a = r (mod m) fkn = 4*k*n a = integer_sqrt(fkn) # now, increase a until a = r (mod m) rm = r % m while a % m != rm: a += 1 ub = fkn + bound**2 while fkn <= a*a <= ub: c = a*a - fkn b = integer_sqrt(c) if b*b == c: return gcd(a + b, n) a += m return n