Exemplo n.º 1
0
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])))
Exemplo n.º 2
0
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]
Exemplo n.º 3
0
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
Exemplo n.º 4
0
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)
Exemplo n.º 5
0
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
Exemplo n.º 6
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)