Ejemplo n.º 1
0
def generate_lists(primemax):
    global plist1, plist2
    plist = lib.list_primes2(primemax)
    plist1, plist2 = [3], [3]
    for i in range(3, len(plist)):
        if plist[i] % 3 == 1: plist1.append(plist[i])
        else: plist2.append(plist[i])
    print(': generated lists, max =', primemax, ', mod3=1 size =', len(plist1),
          ', mod3=2 size =', len(plist2))
Ejemplo n.º 2
0
def initialize_caches(primemax):
    print(': initializing caches with prime limit =', primemax)
    global primecache1, primecache2, paircache1, paircache2
    primelist = lib.list_primes2(primemax)  # starts with 2,3,5,7
    primecache1, primecache2 = [3], [3]  # separately insert 3
    for i in range(3, len(primelist)):  # split cache
        if primelist[i] % 3 == 1: primecache1.append(primelist[i])
        else: primecache2.append(primelist[i])  # will have mod3 value = 2
    print(': generate split prime lists, len(mod3=1) =', len(primecache1),
          ', len(mod3=2) =', len(primecache2))
    paircache1 = list(
        list(False for c in range(len(primecache1)))
        for r in range(len(primecache1)))
    paircache2 = list(
        list(False for c in range(len(primecache2)))
        for r in range(len(primecache2)))
    for i, pi in enumerate(
            primecache1):  # generate mod3=1 pair primality cache
        ibase = pi  # use to shift left based on digits in prime index j
        nextleftshift = 1
        for j, pj in enumerate(primecache1):
            if i == j: continue  # would have factor 11 or 101 or 1001, ...
            if pj >= nextleftshift:
                ibase *= 10
                nextleftshift *= 10
            conc = ibase + pj
            paircache1[i][j] = is_prime(conc)
    print(': generated lookup table for mod3=1')
    for i, pi in enumerate(
            primecache2):  # generate mod3=2 pair primality cache
        ibase = pi
        nextleftshift = 1
        for j, pj in enumerate(primecache2):
            if i == j: continue
            if pj >= nextleftshift:
                ibase *= 10
                nextleftshift *= 10
            conc = ibase + pj
            paircache2[i][j] = is_prime(conc)
    print(': generated lookup table for mod3=2')
    print(': done')
Ejemplo n.º 3
0
import libtkoz as lib

sumways = 5000

# dynamic programming

maxprime = 32
while True:  # increase prime limit until finding a solution
    ways = [0] * (maxprime + 1)
    plist = lib.list_primes2(maxprime)
    ways[0] = 1  # 1 way, nothing, for when first prime selected is itself
    ways[1] = 0  # not prime, no smaller primes
    for p in plist:  # add how many ways i=p+k --> k as sum of primes <= p
        for i in range(p, maxprime + 1):
            ways[i] += ways[i - p]
    solution = -1
    for i, w in enumerate(ways):  # find satisfying number
        if w > sumways:
            solution = i
            break
    if solution != -1:  # found a satisfying number
        print(':', solution, 'can be expressed in', ways[solution], 'ways')
        print(solution)
        break
    maxprime *= 2
Ejemplo n.º 4
0
import libtkoz as lib
import math
import functools

# ~3min with cpython / core2 q8200
# appears to scale linear to sqrt(N)

N = 10**16
modulus = 10**9 + 7
primes = lib.list_primes2(int(math.sqrt(N)))
print(': sieved primes')

# determine max value of k
prod = 1
ktable = [0]
for p in primes:
    prod *= p * p
    if prod > N: break
    ktable.append(0)

# for each k, count how many numbers are divisible by all prime squares in
# every combination of k prime squares


# product of squares, number of factors, next prime index
def recurse(sqprod, numpfactors, nextpi):
    global N, primes, ktable
    maxsq = N // sqprod
    while nextpi < len(primes) and primes[nextpi]**2 <= maxsq:
        recurse(sqprod * primes[nextpi]**2, numpfactors + 1, nextpi + 1)
        nextpi += 1
Ejemplo n.º 5
0
def C(n):
    assert n > 0
    pin = len(lib.list_primes2(n))
    return 6 * (5**(n - pin - 1)) * sum(
        5**(pin - i) * lib.binom_coeff(n - 1, i) for i in range(pin + 1))
Ejemplo n.º 6
0
import libtkoz as lib

factorsexp = 500500
modulus = 500500507

# large enough so pi(sievelim) >= factorsexp # may need up to this many primes
# if not large enough, program will crash with list index out of bounds
sievelim = 8000000

# use a sieve (index i represents 2i+1) (prime=True)
# every time reaching a prime, mark its square
# requires only 1 sweep over the sieve, ~4sec (i5-2540m)

sieve = lib.list_primes2(sievelim, return_sieve=True)
evenval = 2
sievei = 1  # 2*1+1=3 initially
result = 1
counted = 0

while counted < factorsexp:  # iterate over sieve
    if evenval < 2 * sievei + 1:  # more optimal to pick exponent of 2
        result = (result * evenval) % modulus
        evenval *= evenval
        counted += 1
    else:
        if sieve[sievei]:  # prime, multiply this one
            n = 2 * sievei + 1
            result = (result * n) % modulus
            n *= n  # mark square in sieve
            n //= 2  # sieve index of square
            if n < len(sieve): sieve[n] = True  # mark so it is multiplied
Ejemplo n.º 7
0
import libtkoz as lib

smax = 24
modulus = 10**9

# ~4sec (pypy / i5-2540m) and ~50sec (cpython / i5-2540m)

fib = [0, 1]  # generate fibonacci numbers
while len(fib) <= smax:
    fib.append(fib[-2] + fib[-1])

numsums = [0] * (fib[-1] + 1)  # i: sum of numbers whose prime factors sum to i
numsums[0] = 1  # needed for dynamic programming
primes = lib.list_primes2(fib[-1])

for p in primes:
    # if p is added to factorizations of i, those numbers get multiplied by p
    # numsums[i] is sum for numbers using prime factors at most p
    # suppose numsums has sums for numbers using factors below p
    # if p is considered at index i, then we take numbers whose factors sum to
    # i-p and add a p to them, this is equivalent to multiplying those numbers
    # by p so we add that quantity to the index for i
    for i in range(p, len(numsums)):
        numsums[i] = (numsums[i] + p * numsums[i - p]) % modulus
# sum fibonacci indexes
print(sum(numsums[fib[f]] for f in range(2, smax + 1)) % modulus)
Ejemplo n.º 8
0
import libtkoz as lib
import math

divisors = 8
maximum = 10**6  #10**12

primes = lib.list_primes2(maximum)  #1+math.floor(math.sqrt(maximum)))

# find factorizations of how many divisors
# the prime factorization of numbers with that many divisors must have exponents
# 1 less than each factor
dfactorizations = []


def d_factor(factors, n, prevf):
    global dfactorizations, divisors
    if n == divisors:
        dfactorizations.append(factors)
    else:  # factor remaining part recursively
        rem = divisors // n
        while prevf * prevf <= rem:
            if rem % prevf == 0:
                d_factor(factors + [prevf], n * prevf, prevf)
            prevf += 1
        d_factor(factors + [rem], divisors, rem)


d_factor([], 1, 2)
print(':', dfactorizations)

count = 0
Ejemplo n.º 9
0
# find the solution

pn = 2 # approximate p_n with binary method
while 2*int(pn/math.log(pn))*pn < modexceed: pn *= 2
pn //= 2 # step back
add = pn // 2
while add != 0:
    pn += add
    if 2*int(pn/math.log(pn))*pn > modexceed: pn -= add
    add //= 2
print(': estimated p_n =',pn,'with n ~=',int(pn/math.log(pn)))
# step back to find prime near p_n
while not lib.miller_rabin_verified(pn): pn -= 1
print(': found prime value p_n =',pn)
# count primes
n = len(lib.list_primes2(pn))
print(': found n =',n)
# count down if needed
while 2*n*pn > modexceed:
    n -= 1
    pn -= 1 # find previous prime
    while not lib.miller_rabin_verified(pn): pn -= 1
# go up to first n value that exceeds
while 2*n*pn <= modexceed:
    n += 1
    pn += 1
    while not lib.miller_rabin_verified(pn): pn += 1
print(': found p_',n,' = ',pn,' with product 2*n*p_n = ',2*n*pn,sep='')
# the only thing left now is to make sure the prime index n is odd so we get
# 2*n*p_n instead of 2 as the remainder
if n % 2 == 0: n += 1
Ejemplo n.º 10
0
import libtkoz as lib
import math

# brute force with prime cache
cache = lib.list_primes2(10000,return_set=True)
cachemax = max(cache)
def is_prime(n):
    if n <= cachemax: return n in cache
    return lib.prime(n)

n = 9
while True: # loop to test composites
    if not is_prime(n):
        satisfiesconjecture = False
        for s in range(1, int(math.sqrt(n//2))+1): # find a square that works
            if is_prime(n - 2*s*s):
                satisfiesconjecture = True
                break
        if not satisfiesconjecture:
            print(n)
            break
    n += 2
Ejemplo n.º 11
0
import libtkoz as lib

pval = 10**8
modulus = 10**9 + 7

# improved to sublinear pi sequence checking (after generating prime list)
# primes uses O(n) memory, primeset uses O(n/logn) and so does picache
# pi sequences require about logn/loglogn steps
# main loop looks at all primes (O(n/logn)) so overall is about O(n/loglogn)

# make prime list for iteration and prime set for fast primality checking
primes = lib.list_primes2(pval)
print(': listed primes up to', pval)
# values of pi(n) for O(1) computation, go up to maximum pi(n) value
picache = []
primeset = set()  # make for fast primality checking of smaller numbers
for i, p in enumerate(primes):  # pi(p)=i+1
    primeset.add(p)
    while len(picache) < p:
        picache.append(i)
    picache.append(i + 1)
    if p > len(primes): break
print(': generated pi(n) cache up to', len(picache) - 1)

longest = 2  # find longest possible pi sequence length
n = len(primes)  # (pval,pi(pval))
while n != 1:
    n = picache[n]
    longest += 1
print(': longest pi sequence length is', longest)
Ejemplo n.º 12
0
import libtkoz as lib

arange = 999 # -999 to 999
brange = 1000 # -1000 to 1000
pseqlenparam = 100 # estimate for longer sequences to determine prime cache size

# quadratic function is x^2+ax+b
# computing next: f(x+1) - f(x) = (x^2+2x+1+ax+a+b) - (x^2+ax+b)
# = 2x+1+a --> use this as difference to compute next more efficiently

# generate a set of primes to quickly look up
# if x may go up to 100, 100^2+1000*100+1000 ~= 10^5 --> seems reasonable
# pick the largest term at x=100
ptablemax = max(pseqlenparam**2, pseqlenparam*arange, brange)
ptable = lib.list_primes2(ptablemax,return_set=True)
def prime(n):
    global ptable
    global ptablemax
    return (n <= ptablemax and n in ptable) or lib.prime(n)
print(': listed', len(ptable), 'primes <=', ptablemax)

# f(x) = x^2 + ax + b
# f(0) = b --> b must be prime
# f(1) = 1 + a + b --> if b odd then a must be odd
# f(x+1) - f(x) = 2x + 1 + a --> a must be odd so the step size is even
if arange % 2 == 0: arange -= 1 # ensure it is odd
mostprimes = 0
amost, bmost = 0, 0
for b in range(3, brange+1, 2):
    if not prime(b): continue
    for a in range(-arange, arange+1, 2):
Ejemplo n.º 13
0
import libtkoz as lib

truncprimesexist = 11
primecachesize = 100000  # maximum number to cache
# cut down from 1 million made it a lot faster
primecache = lib.list_primes2(primecachesize, return_set=True)


# test primality with cache
def is_prime(p):
    global primecachesize
    global primecache
    if p < primecachesize: return p in primecache
    else: return lib.prime(p)


# functions to test prime truncatable properties, assumes number itself is prime
def right_trunc(p):  # just divide by 10 (integer division)
    p //= 10
    while p != 0:
        if not is_prime(p): return False
        p //= 10
    return True


def left_trunc(p):  # use strings for simplicity
    while p >= 10:  # at least 2 digits, can truncate another
        p = int(str(p)[1:])
        if not is_prime(p): return False
    return True
Ejemplo n.º 14
0
import libtkoz as lib
import math

maximum = 10**8

# ~1min and 2GiB RAM (pypy / i5-2540m)
# start with a prime set for fast prime checking and a list of booleans for each
# number that starts as true, once a composite d+n/d is found mark it false
# only need to test d up to sqrt(n) because if d>sqrt(d) then n/d<sqrt(d) but
# n/d is also a divisor so we would have already tested n/d+n/(n/d)=d+n/d

# list primes up to 1 more since if d=n then n+n/n=n+1
# make a set of primes for fast prime testing (set containment)
primes = lib.list_primes2(maximum + 1, return_set=True)
print(': listed primes up to', maximum + 1)

# set to false once a composite d+n/d is found
nums = [True] * (maximum + 1)

for d in range(1, 1 + int(math.sqrt(maximum))):
    nd = d  # n/d value, d/d=1, 2d/d=2, ..., incremented in loop
    for n in range(d * d, maximum + 1, d):  # every number d divides
        if not ((d + nd) in primes): nums[n] = False
        nd += 1
# sum indexes in nums list
print(sum(n for n in range(maximum + 1) if nums[n]))
Ejemplo n.º 15
0
import libtkoz as lib
import math

limit = 1000000

primes = lib.list_primes2(limit, return_set=True)

# brute force try everything, ~0.5 sec (i5-2540m)
circulars = {2, 5}
for n in range(3, limit, 2):
    if not n in primes or n in circulars: continue
    nn = n
    max10pow = int(math.log10(n))  # largest exp of 10 in number
    circular = True
    for i in range(max10pow):  # do all rotations
        nn = (nn // 10) + (nn % 10) * (10**max10pow)
        if not nn in primes:
            circular = False
            break
    if circular:  # insert all rotations
        print(': inserting rotations of', n)
        circulars.add(n)
        nn = n
        for i in range(max10pow):
            nn = (nn // 10) + (nn % 10) * (10**max10pow)
            circulars.add(nn)
            print(':', nn)
print(':', sorted(list(circulars)))
print(len(circulars))
Ejemplo n.º 16
0
import libtkoz as lib

seqlen = 3  # currently hardcoded, has no effect
digits = 4

# brute force
primes = lib.list_primes2(10**digits)
print(': listed', len(primes), 'primes')


def is_prime(n):  # assumes it would be in the primes list, binary search
    global primes
    l, h = 0, len(primes)
    while l != h:
        mid = (l + h) // 2
        if primes[mid] >= n: h = mid
        else: l = mid + 1
    return l < len(primes) and primes[l] == n


# binary search for lowest 4 digit prime
l, h = 0, len(primes)
while l != h:
    m = (l + h) // 2
    if primes[m] >= (10**(digits - 1)): h = m
    else: l = m + 1
print(': start prime index', l, 'is', primes[l])

done = False
for i in range(l, len(primes)):  # select first prime
    pi = primes[i]
Ejemplo n.º 17
0
import libtkoz as lib

familysize = 8
# assert familysize in [8, 9, 10]

primelim = 100000
primecache = lib.list_primes2(primelim, return_set=True)


def is_prime(n):
    global primelim, primecache
    if n > primelim: return lib.prime(n)
    return n in primecache


# suppose we replace some number of digits, use digit sum for 3 divisibility
# if d digits are replaced, digit sum starts at s if the digits are 0 then
# the digit sums will be s,s+d,s+2d,...,s+9d
# at least 8 must not be divisible by 3
# if d is not divisible by 3 then 3 or 4 of the sums are divisible by 3
# at most 7 could be prime in that case so for 8,9,10 digit replacements,
# we must replace 3,6,9,... digits


def advance_permutation(l):  # lexicographic order, increasing order
    i1 = len(l) - 1
    while i1 > 0 and l[i1 - 1] >= l[i1]:
        i1 -= 1  # break decrease order
    i1 -= 1
    if i1 == -1: return None  # already maximum
    i2 = len(l) - 1
Ejemplo n.º 18
0
import libtkoz as lib

limit = 1000000
primes = lib.list_primes2(limit)
primeset = set(primes)  # for fast lookup

longestseq = 1
bestprime = 0

for i in range(len(primes)):
    if i > limit / longestseq: break  # cant make longer sequence
    total = sum(primes[i:i + longestseq])
    seqlen = longestseq
    for j in range(i + longestseq, len(primes)):
        total += primes[j]
        if total >= limit: break  # done for this starting number
        seqlen += 1
        if total in primeset:
            print(':', total, 'is sum of', seqlen, 'primes, start =',
                  primes[i])
            longestseq, bestprime = seqlen, total
print(bestprime)
Ejemplo n.º 19
0
import libtkoz as lib

primelim = 5000
modulus = 10**16

# generate primes and build sets 1 element at a time
# maintain a list than keeps track of how many subsets sum to each number
# keep a running cumulative sum of primes so the list can be dynamically
# expanded as the highest possible sum increases with each new prime
# lastly list primes up to the sum of primes in the set and use those as the
# indexes for computing the sum (count subsets with prime sums)
# takes ~2min (cpython / i5-2540m)

pset = lib.list_primes2(primelim - 1)

# number of subsets with each sum
setswithsum = [1]  # start with empty set

# build the set 1 element at a time
n = 0
psumcumulative = 0  # keep track of this to dynamically grow the list
for p in pset:
    n += 1
    psumcumulative += p
    # sets with sum i = original amount + p added to sets with sum i-p
    newlist = setswithsum[:] + ([0] * p)
    for i in range(p, psumcumulative + 1):
        newlist[i] = (newlist[i] + setswithsum[i - p]) % modulus
    setswithsum = newlist
#    assert sum(setswithsum)%modulus == (2**n)%modulus
Ejemplo n.º 20
0
import libtkoz as lib

setsize = 5  # number of primes in prime pair set
assert setsize >= 2

# prime cache to speed up primality checking
pclim = 1000000
pcset = lib.list_primes2(pclim, return_set=True)


def is_prime(n):
    if n <= pclim: return n in pcset
    return lib.prime(n)


print(': generated primality checking cache with limit =', pclim)

# brute force with some optimizations, took ~23min (i5-2540m) (very long !!!)
# first observation: 2 or 5 cant be in the set
# every prime in the set must have same mod3 value (all 1 or all 2)
# if 1 and 2 are mixed, concatenating those 2 gives a number divisible by 3
# based on this, split the prime caches based on their mod3 value
# additionally, 3 may be used in these so each cache half must have 3

# the caches take a very long time to generate relative to how long the
# recursion spends searching candidate prime sets
# just by observation, recursing was almost instant, even for large limits

primecache1, primecache2 = [], []  # split based on mod3 value
paircache1, paircache2 = [[]], [[]]
Ejemplo n.º 21
0
import libtkoz as lib
import math

nlim = 150 * 10**6
steps = [1, 3, 7, 9, 13, 27]

# use an observation for efficiency, faster with miller rabin test
# prime list eliminates lots of candidates, then the amount of use of the
# miller rabin test is small so it can complete quickly after that
# ~7sec (pypy / i5-2540m)
# if some n=qx+r, a prime q, integer x, and remainder r,
# n^2+s = q^2*x^2 + 2qxr + r^2+s
# so if q | r^2+s then q | n^2+s

plistsize = int(math.sqrt(nlim))
plist = lib.list_primes2(plistsize)

candidates = []
for n in range(10, nlim, 10):
    # for each n, if a prime q divides r^2+s then it cant be a solution number
    fail = False  # n cant be a candidate if this becomes true
    for q in plist:  # use primes to eliminate many possibilities
        # skip primes above n since for primality, we only need to test
        # up to n for n^2+s
        if fail or q > n: break
        r = n % q
        r *= r  # represents r^2
        for s in steps:
            if (r + s) % q == 0:
                fail = True
                break
Ejemplo n.º 22
0
import libtkoz as lib
import math

limit = 10**8

# sieve, then pick a prime p and count how many primes q >= p such that
# pq <= limit, so its summing pi(limit/p)-pi(p-1) for every p<=sqrt(limit)
# sieving primes takes long but summing is fast since computing pi(n) can be
# done efficiently with a prime list and binary search
# ~18sec (cpython / i5-2540m)

# start by listing primes up to half the limit since 2*p
plist = lib.list_primes2(limit // 2)
limitsqrt = int(math.sqrt(limit))
print(': listed primes up to', limit // 2)

# for every prime p up to sqrt(limit), count how many primes there are from p
# to limit/p, this can be done efficiently with binary search
# the desired value is pi(limit/p) - pi(p-1), pi(n) is count of primes <= n


# count primes up to n, correct results if n < next prime after plist[-1]
def pi(n):
    global plist
    # find index of first prime to exceed n, pi(n) is num primes below this
    l, h = 0, len(plist)  # partition
    while l != h:
        m = (l + h) // 2  # middle point, splits are [l,m] and [m+1,h)
        if plist[m] > n: h = m
        else: l = m + 1
    return l
Ejemplo n.º 23
0
import libtkoz as lib
import math

limit = 50000000

# brute force by looping over a prime list, ~1sec (i5-2540m)
# begin by listing primes up to sqrt(limit)
primes = lib.list_primes2(int(math.sqrt(limit)))
print(': generated primes up to', int(math.sqrt(limit)))
sieve = set()  # numbers that are expressible as the sum
# this doubled speed, rather than allocate a length 50 million array

for p2 in range(len(primes)):
    sum2 = primes[p2]**2  # sum the square, wont exceed limit
    for p3 in range(len(primes)):
        sum23 = sum2 + primes[p3]**3
        if sum23 >= limit: break
        for p4 in range(len(primes)):
            sum234 = sum23 + primes[p4]**4
            if sum234 >= limit: break
            sieve.add(sum234)
print(len(sieve))