def fermats_diff_of_squares(N): if N % 2 == 0: raise ValueError("Must be given odd N") steps = Steps() steps.add_sqrt(N) x = int(math.floor(math.sqrt(N))) t, r = 2 * x + 1, x * x - N isq, isq_steps = is_square(r) steps.append(isq_steps) while (not isq): r += t t += 2 isq, isq_steps = is_square(r) steps.append(isq_steps) x = (t - 1) / 2 steps.add_sqrt(r) y = int(math.sqrt(r)) return x - y, x + y, steps
def harts_one_line(N, L=-1): steps = Steps() if L == -1: L = N for i in xrange(1, L): steps.add_sqrt(N * i) s = int(math.ceil(math.sqrt(N * i))) steps.add_mod() m = (s * s) % N isq, isq_steps = is_square(m) steps.append(isq_steps) if (isq): break steps.add_sqrt(m) t = math.sqrt(m) f1, gcd_steps = gcd(s - t, N) f2 = N / f1 steps.append(gcd_steps) return f1, f2, steps
def trial_division(N, when_to_stop=None): primes_list = get_primes() m, pi, p = N, 0, 2 steps = Steps() factors = [] if when_to_stop == None: when_to_stop = math.sqrt(N) steps.add_sqrt(N) while (p <= when_to_stop): steps.add_mod() if m % p == 0: m = m / p factors.append(p) else: pi += 1 p = primes_list[pi] num_unfactored = 0 if m != 1: factors.append(m) if m not in primes_list: num_unfactored = 1 return factors, steps, num_unfactored
def lehmans_var_of_fermat(N): s3n = int(math.ceil(N**(1.0 / 3.0))) steps = Steps() for k in xrange(1, s3n + 1): steps.add_sqrt(k * N) sk = 2.0 * math.sqrt(k * N) steps.add_exp(sk + N, 1.0 / 6.0) steps.add_sqrt(k) for a in xrange( int(math.ceil(sk)), int( math.floor(sk + N**(1.0 / 6.0) / (4.0 * math.sqrt(k))) + 1)): b = a * a - 4 * k * N isq, isq_steps = is_square(b) steps.append(isq_steps) if isq: my_gcd, gcd_steps = gcd(a + math.sqrt(b), N) steps.append(gcd_steps) return my_gcd, N / my_gcd, steps raise Exception("should not get here ")
def is_square(x): steps = Steps() steps.add_sqrt(x) return x >= 0 and int(math.sqrt(x)) == math.sqrt(x), steps