import libtkoz as lib maxn = 64 * 10**6 # this is pretty much a brute force method, cpython needs over 2GiB RAM to solve # it, pypy did it with 500MiB, ~20sec (pypy / i5-2540m) # use a sieve to sum squares of divisors sieve = [1] * maxn sieve[0] = 0 for factor in range(2, maxn): # sum squares f2 = factor**2 for i in range(factor, maxn, factor): sieve[i] += f2 # add square to sum for numbers factor divides # sum all n that are perfect squares print(sum(n for n in range(1, maxn) if lib.is_square(sieve[n])))
import libtkoz as lib import math digits = 100 maxnum = 100 # TODO change to 100 showapprox = False # display fraction approximation used showdigits = False # display calculated digits # begin by approximating each square root with a fraction by using the # continued fraction expansion with its recurrence relation # then use long division to calculate the digits digitsum = 0 for num in range(2,maxnum+1): if lib.is_square(num): continue # only sum for irrational square roots n = math.floor(math.sqrt(num)) # first 2 convergents are n/1 and (n*r+1)/r with r=floor(2n/(num-n^2)) r = (2*n) // (num - n**2) a1, a2 = n, n*r+1 # numerator a2 b1, b2 = 1, r # denomenator b2 # fractional part, after a2/b2 convergent can be calculated to be # (sqrt(num)+n-r*(num-n^2))/(num-n^2) rem = (num, n-(num-n**2)*r, 0, num-n**2) # (sqrt,int) / (sqrt,int) # compute fraction until denomenator > 10**digits (error < 10**(-digits)) while b2 < 10**digits: # calculating next constant based on p064 solution rem = (rem[2], rem[3], rem[0], rem[1]) den = rem[2] - rem[3]**2 # denomenator for next fraction assert den % rem[1] == 0, 'theoretical assumption failure' rem = (rem[2], -rem[3], 0, den // rem[1]) intpart = (rem[1] + n) // rem[3]
maxnum = 10000 printsequences = False # toggle to see info about the expansions # brute force, evaluate series for every square root # at each step, we have some value x to write as i+f (integer + 0<f<1) # initially, lets say we start with sqrt(n), use a=floor(sqrt(n)) # so we start with sqrt(n) = a + (sqrt(n) - a)/1 # we must repeatedly write the fractional part as 1/(some value > 1) # the method used below is based on some observations and no justification is # given to suggest they are always true oddcount = 0 for n in range(2, maxnum + 1): if lib.is_square(n): continue # skip perfect squares a = math.floor(math.sqrt(n)) rem = (n, -a, 0, 1) # [sqrt(n) - a] / [sqrt(0) + 1] loop = [] # loop created in the continued fraction expansion while True: # perform an iteration, stop once denomenator is 1 again # this is an observation that cycling eventually results in a fractional # part with 1 denomenator so we get sqrt(n)-a as a fractional part again rem = (rem[2], rem[3], rem[0], rem[1]) # flip fraction den = rem[2] - rem[3]**2 # denonator after multiply by conjugate # obsernation that the numerator constant gets divided out assert den % rem[1] == 0, 'failure ' + str(den) + ' % ' + str( rem[1]) + ' != 0' rem = (rem[2], -rem[3], 0, den // rem[1] ) # after multiply by conjugate # rem[1] (constant) can be subtracted by up to rem[1]+a # it must be multiple of denomenator, this calculates integer part
import libtkoz as lib exceed = 1000000 # find M such that there are more than this many smaller # cuboids with integer length shortest path # if the cuboid has dimensions a<=b<=c then its 3 possible shortest paths are # sqrt(a^2+(b+c)^2), sqrt((a+b)^2+c^2), sqrt(b^2+(a+c)^2) # the shortest is sqrt(a^2+b^2+c^2+2ab) # brute force, try all cubes, ~20min (i5-2540m) intcount = 0 # with integer shortest path M = 0 # maximum cuboid dimension while intcount <= exceed: M += 1 # use M=c, loop for a and b for b in range(M,0,-1): for a in range(b,0,-1): if lib.is_square(a*a+b*b+M*M+2*a*b): intcount += 1 print(': M =', M, 'with', intcount, 'solutions') print(M)
import libtkoz as lib import math maxD = 1000 showminx = False # toggle to show/hide some output showkcycle = False # diophantine equations x^2 - D * y^2 = 1 # no solutions if D is a perfect square, find minimal x largestminx = 0 bestD = 0 for D in range(2, maxD+1): if lib.is_square(D): continue # only trivial (x,y)=(1,0) solution # chakravala method, starting values a, b = int(math.floor(math.sqrt(D))), 1 k = a**2 - D kcycle = [k] while k != 1: # eventually terminates with k=1, solution to pells equation # pick m congruent to -a (mod k), m <= floor(sqrt(D)) < m+abs(k) m = 0 # find with a loop absk = abs(k) intD = math.floor(math.sqrt(D)) for mm in range(intD, intD + absk): if (a + b*mm) % absk == 0: m = mm break assert m != 0 # by induction, these can be shown to be true assert (a*m + D*b) % absk == 0 assert (a + b*m) % absk == 0 assert (m**2 - D) % absk == 0
import libtkoz as lib exceed = 1000000 # similar to last solution, start by picking c, longest side # then a+b has some amount of solutions based on 2 cases since a can be varied # as a function of b and vice versa, much faster ~3sec (i5-2540m) c = 0 intcount = 0 while intcount <= exceed: c += 1 # we have the shortest side is sqrt((a+b)^2+c^2) # find values for a+b that dont exceed 2c and make the sqrt integer # 2 cases to consider, if a+b<=c then solutions for a+b are (use a+b=z) # (1,z-1), (2,z-2), ..., (floor(z/2),ceil(z/2)) --> floor((a+b)/2) solutions # if a+b>c then (using a+b=z again) the solutions are # substitute cz as ceil(z/2) and fz as floor(z/2) # (cz,fz), (cz+1,fz-1), ..., (cz+(c-cz), fz-(c-cz)) --> 1+c-cz solutions for apb in range(2, c + 1): if not lib.is_square(apb * apb + c * c): continue intcount += apb // 2 for apb in range(c + 1, 2 * c + 1): if not lib.is_square(apb * apb + c * c): continue intcount += 1 + c - (apb + 1) // 2 # ceil(apb/2) = floor((apb+1)/2) print(': M =', c, 'with', intcount, 'solutions') print(c)