예제 #1
0
def main():
    primes = prime_sieve(100_000)

    @lru_cache(maxsize=None)
    def is_prime(n, primes=primes, primes_set=frozenset(primes)):
        if n < 100_000:
            return n in primes_set

        for p in primes:
            if not n % p:
                return False
            if p*p > n:
                return True

    def count_sets(cnt, prev, digits):
        if not digits:
            return cnt + 1

        for i in range(1, len(digits)+1):
            for p in permutations(digits, i):
                if i == 1:
                    if p[0] not in "2357":
                        continue
                elif p[-1] not in "1379":
                    continue

                x = int("".join(p))

                if x > prev and is_prime(x):
                    cnt = count_sets(cnt, x, digits.difference(p))
        return cnt

    return count_sets(0, 0, frozenset("123456789"))
예제 #2
0
파일: p146.py 프로젝트: icot/euler
def main():
    limit = int(150e6)
    primes = prime_sieve(int(150e6))

    N = int(ceil(math.sqrt(150e6)))
    for n in range(N):
        candidates
예제 #3
0
def solve_for_n(n, sieve_size=10000000):
    primes, sieve = prime_sieve(sieve_size)

    for prime in primes:
       
        dig_array = digit_array(prime / 10)
        exn = explode_number(prime)
        
        for i in range(10):
            if dig_array[i] == 0:
                continue

            misses = 0
            inds = inds_of_n(exn, i)
            if inds == []:
                continue

            for testnum in range(i + 1, 10): #not correct bound
                if misses + i > n:
                    break
                
                rplc = replace_inds(exn, inds, testnum)
                if sieve[rplc] == 0:
                    misses += 1
            if misses + i <= 10 - n:
                return prime
    return None
예제 #4
0
파일: p108.py 프로젝트: icot/euler
def gennum(ndivs):
    exps = utils.factors(ndivs)
    exps.reverse()
    exps = [exp - 1 for exp in exps]
    primes = utils.prime_sieve(100)
    g = izip(primes, exps)
    n = [pow(item[0], item[1]) for item in g]
    return reduce(lambda x, y: x * y, n)
예제 #5
0
 def fn(self):
     count = 0
     primes = prime_sieve(self._limit)
     for i, v in enumerate(primes):
         if v:
             circular_nums = self.circular_num(i)
             if all(primes[p] for p in circular_nums):
                 count += 1
     return count
예제 #6
0
파일: 609.py 프로젝트: JJTimmons/euler
def prime_counting(target):
    target += 1
    primes = utils.prime_sieve(target + 1)

    pi_counts = [0] * (target + 1)
    primes_seen = 0
    for n in range(target + 1):
        if primes[n]:
            primes_seen += 1
        pi_counts[n] = primes_seen

    ks = [0] * (target + 1)
    nodes = {}
    last_pi = None
    last_node = None
    last_prime = False
    cut_off = pi_counts[target]
    for n in range(target):
        pi = pi_counts[n]
        if pi == last_pi and not last_prime:
            for c in last_node.cs:
                ks[c] += 1
            nodes[n] = last_node
            continue

        # if pi > cut_off:
        #     continue

        parent = None
        comp = True
        if pi > 0:
            parent = nodes[pi]
            comp = not primes[n]

        new_node = node(n, comp, parent)
        # print n, new_node.cs
        for c in new_node.cs:
            ks[c] += 1

        nodes[n] = new_node
        last_node = new_node
        last_pi = pi
        last_prime = primes[n]

    def P(n):
        """ Let P(n) be the product of all p(n,k) that are larger than 0. """
        ps = []
        for i, count in enumerate(ks):
            if count > 0:
                # print i, count
                ps.append(count)
        return reduce(lambda x, y: x * y, ps)

    return P(target - 1)
예제 #7
0
def hamming_numbers(limit=10**9, hamming_cutoff=100):

    primes = [
        p for p in utils.prime_sieve(limit, as_list=True)
        if p > hamming_cutoff and p < limit
    ]
    hammings = [True] * limit
    for n in primes:
        for m in range(n, limit, n):
            hammings[m] = False

    print len([h for h in hammings if h is True])
예제 #8
0
def main():
    primes = prime_sieve(1000000)
    primes_set = set(primes)

    cnt = 0

    for p in primes:
        for r in rotations(p):
            if r not in primes_set:
                break
        else:
            cnt += 1
    return cnt
예제 #9
0
파일: 193.py 프로젝트: JJTimmons/euler
def squarefree_approach_1(limit=2**50):

    upper_bound = int(math.floor(math.sqrt(limit)))

    primes = utils.prime_sieve(upper_bound, as_list=True)

    squares = set()
    for p in primes:
        sqr = p**2
        for q in xrange(sqr, limit / 2, sqr):
            squares.add(q)

    return len(squares)
예제 #10
0
def main():
    # n cannot be prime^k (k = [1, 2, ...]) because prime^k and phi(prime^k)
    # cannot be a permutation of each other

    lim = 10**7
    primes = prime_sieve(4000)
    last_idx = len(primes)-1
    # the max prime <= sqrt(10**7) is 3137
    middle_idx = bisect_left(primes, 3137)

    def candidate_primes(low_idx):
        for high_idx in range(last_idx, low_idx, -1):
            if primes[low_idx]*primes[high_idx] <= lim:
                yield high_idx

    class Number(object):
        """Number which is the product of two primes"""

        def __init__(self, low_idx, gen):
            self.low_idx = low_idx
            self.gen = gen
            low = primes[low_idx]
            high = primes[next(gen)]
            self.number = low*high
            self.phi = (low-1)*(high-1)

        def __lt__(self, other):
            return self.number*other.phi < other.number*self.phi

    queue = []

    for low_idx in range(middle_idx, -1, -1):
        heappush(queue, Number(low_idx, candidate_primes(low_idx)))

    while queue:
        number = heappop(queue)

        if is_permutation(number.number, number.phi):
            return number.number

        try:
            heappush(queue, Number(number.low_idx, number.gen))
        except StopIteration:
            pass
예제 #11
0
파일: 193.py 프로젝트: JJTimmons/euler
def squarefree_approach_2(limit=2**50):
    upper_bound = int(math.floor(math.sqrt(limit)))

    # start at the top prime
    primes = utils.prime_sieve(upper_bound, as_list=True)
    primes = sorted(primes, reverse=True)
    primes_sqrd = [p**2 for p in primes]

    # divide the limit by the number of times this fits within in it
    print len(primes_sqrd)
    prev_counts = {}
    non_squares = 0
    for (i, p) in enumerate(primes_sqrd):
        count = int(math.floor(limit / p)) + 1
        count -= sum(
            [int(math.floor(prev_p / p)) for prev_p in primes_sqrd[:i]])
        non_squares += count
        prev_counts[p] = count
    return limit - non_squares
예제 #12
0
def main():
    # n cannot be prime^k (k = [1, 2, ...]) because prime^k and phi(prime^k)
    # cannot be a permutation of each other

    lim = 10**7
    primes = prime_sieve(4000)
    last_idx = len(primes) - 1
    # the max prime <= sqrt(10**7) is 3137
    middle_idx = bisect_left(primes, 3137)

    def candidate_primes(low_idx):
        for high_idx in range(last_idx, low_idx, -1):
            if primes[low_idx] * primes[high_idx] <= lim:
                yield high_idx

    class Number(object):
        """Number which is the product of two primes"""
        def __init__(self, low_idx, gen):
            self.low_idx = low_idx
            self.gen = gen
            low = primes[low_idx]
            high = primes[next(gen)]
            self.number = low * high
            self.phi = (low - 1) * (high - 1)

        def __lt__(self, other):
            return self.number * other.phi < other.number * self.phi

    queue = []

    for low_idx in range(middle_idx, -1, -1):
        heappush(queue, Number(low_idx, candidate_primes(low_idx)))

    while queue:
        number = heappop(queue)

        if is_permutation(number.number, number.phi):
            return number.number

        try:
            heappush(queue, Number(number.low_idx, number.gen))
        except StopIteration:
            pass
예제 #13
0
def main():
    lim = 50 * 10**6
    lim_square = int((lim - 2**3 - 2**4)**(1 / 2))
    lim_cube = int((lim - 2**2 - 2**4)**(1 / 3))
    lim_fourth = int((lim - 2**2 - 2**3)**(1 / 4))

    primes = prime_sieve(lim_square)

    squares = [p**2 for p in primes]
    cubes = [p**3 for p in primes if p <= lim_cube]
    fourths = [p**4 for p in primes if p <= lim_fourth]

    numbers = set([
        square + cube + fourth for fourth in fourths for cube in cubes
        if fourth + cube < lim for square in squares
        if fourth + cube + square < lim
    ])

    return len(numbers)
예제 #14
0
def main():
    LIMIT = 28123
    primes = prime_sieve(int(sqrt(LIMIT)))
    a_numbers = [i for i in range(12, LIMIT+1) if sum_of_proper_divisors(i, primes) > i]
    a_numbers_set = frozenset(a_numbers)

    def not_sum(n):
        lim = n//2

        for a in a_numbers:
            if a > lim:
                break

            if n - a in a_numbers_set:
                return False

        return True

    return sum(filter(not_sum, range(LIMIT, 0, -1)))
예제 #15
0
def main():
    primes = prime_sieve(100_000)
    res = 0

    for prime in primes:
        if prime < 7:
            res += prime
            continue
        f1, f2 = prime - 1, 1
        while f1 % 2 == 0:
            f1 //= 2
            f2 *= 2
        while f1 % 5 == 0:
            f1 //= 5
            f2 *= 5
        if f1 == 1 or pow(10, f2, prime) == 1:
            continue
        res += prime

    return res
예제 #16
0
def main():
    lim = 1000000
    primes = prime_sieve(lim)
    primes_set = frozenset(primes)

    cnt, res = 21, 953

    for i in range(len(primes)-21):
        s = primes[i]

        for k in range(i+1, len(primes)):
            s += primes[k]

            if s > lim: break

            if s in primes_set and k - i > cnt:
                cnt = k - i
                res = s

    return res
예제 #17
0
def main():
    lim = 50*10**6
    lim_square = int((lim - 2**3 - 2**4) ** (1/2))
    lim_cube = int((lim - 2**2 - 2**4) ** (1/3))
    lim_fourth = int((lim - 2**2 - 2**3) ** (1/4))

    primes = prime_sieve(lim_square)

    squares = [p**2 for p in primes]
    cubes = [p**3 for p in primes if p <= lim_cube]
    fourths = [p**4 for p in primes if p <= lim_fourth]

    numbers = set([
        square + cube + fourth
            for fourth in fourths
            for cube in cubes if fourth + cube < lim
            for square in squares if fourth + cube + square < lim
    ])

    return len(numbers)
예제 #18
0
def main():
    lim = 1000000
    primes = prime_sieve(lim)
    primes_set = frozenset(primes)

    cnt, res = 21, 953

    for i in range(len(primes) - 21):
        s = primes[i]

        for k in range(i + 1, len(primes)):
            s += primes[k]

            if s > lim: break

            if s in primes_set and k - i > cnt:
                cnt = k - i
                res = s

    return res
예제 #19
0
def main():
    primes = prime_sieve(8500)

    @lru_cache(maxsize=None)
    def check(p1, p2):
        return is_prime(int(f'{p1}{p2}')) and is_prime(int(f'{p2}{p1}'))

    def candidates(p):
        for i in range(p[-1]+1, len(primes)):
            if all(check(primes[i], primes[j]) for j in p):
                if len(p) == 4:
                    yield (*p, i)
                else:
                    yield from candidates((*p, i))

    for i in range(len(primes)):
        try:
            quint = next(candidates((i,)))
            return sum(primes[x] for x in quint)
        except StopIteration:
            pass
예제 #20
0
def main():
    primes = prime_sieve(20000)
    primes_set = frozenset(primes)

    t = product = 0

    for b in primes: # b has to be prime (0^2+0*a+b=b)
        if b > 1000:
            break

        for a in (p - b - 1 for p in primes): # n=1, a+b+1 has to be prime
            if a > 1000:
                break

            n = 0
            while n*n + a*n + b in primes_set:
                if n > t:
                    t, product = n, a*b
                n += 1

    return product
예제 #21
0
def main():
    primes = prime_sieve(20000)
    primes_set = frozenset(primes)

    t = product = 0

    for b in primes:  # b has to be prime (0^2+0*a+b=b)
        if b > 1000:
            break

        for a in (p - b - 1 for p in primes):  # n=1, a+b+1 has to be prime
            if a > 1000:
                break

            n = 0
            while n * n + a * n + b in primes_set:
                if n > t:
                    t, product = n, a * b
                n += 1

    return product
예제 #22
0
def prime_generating_integers(upper_limit=1000):
    """
        Notes:
            1. Only even integers. Any odd integer + 1 won't be prime
            2. Relatedly, can filter on only number one less than a prime, since
                the num divided by itself == 1, so n+1 needs to be prime
            3. Add one to the sum
    """
    start = time.time()
    PRIME_LIST = utils.prime_sieve(upper_limit, True)
    PRIMES = set(PRIME_LIST)

    print(time.time() - start)
    start = time.time()

    ANS = set([p - 1 for p in PRIME_LIST if 2 + p / 2 in PRIMES])
    for i, p in enumerate(PRIME_LIST):
        for n in range(p, upper_limit, p):
            if n in ANS:
                while n % p == 0:
                    if p + n / p not in PRIMES:
                        ANS.discard(n)
                        break
                    p *= PRIME_LIST[i]
                p = PRIME_LIST[i]
            if n in ANS:
                while n % p == 0:
                    if p + n / p not in PRIMES:
                        ANS.discard(n)
                        break
                    p += PRIME_LIST[i]

    print(time.time() - start)
    start = time.time()

    assert all(
        [n in ANS for n in [2, 6, 30, 42, 58, 78, 210, 310, 330, 382, 462]])
    assert all([n not in ANS for n in [8, 12, 26, 32, 36, 270, 378]])

    return sum(ANS) + 1  # also include 1...
예제 #23
0
def prime_pair_sets(limit=800000, key_limit=670, target_l=4):
    """
        1. first create all pairings between numbers
        2. then try and find the set with the greatest common value
    """

    P_SET = utils.prime_sieve(limit)
    P_SIEVE = [x for x, p in enumerate(P_SET) if p]

    # cpls = prime couples
    cpls = {p: set([p]) for p in P_SIEVE}
    for p in [p for p in P_SIEVE if p > 10]:
        prime_string = str(p)
        for i in range(1, len(prime_string)):
            f_half = prime_string[:i]
            f_half_int = int(f_half)

            s_half = prime_string[i:]
            if s_half[0] == "0":
                # took way too long to find this
                continue
            s_half_int = int(s_half)

            flipped = int(s_half + f_half)
            if flipped > limit:
                continue

            if P_SET[f_half_int] and P_SET[s_half_int] and P_SET[flipped]:
                cpls[f_half_int].add(s_half_int)
                cpls[s_half_int].add(f_half_int)

    assert permute_add(cpls, cpls[673], set([673]), 4) == set([673, 3, 109, 7])

    best_set = []
    for k in [k for k in sorted(cpls.keys(), reverse=True) if k > key_limit]:
        local_best = permute_add(cpls, cpls[k], set([k]), target_l)
        if compare_sets(local_best, best_set):
            best_set = local_best
    print best_set, sum(best_set)
예제 #24
0
def main():
    primes = [p for p in prime_sieve(10000)
              if p > 1000 and p not in {1487, 4817, 8147}]
    primes_set = frozenset(primes)

    def anagram_hash(num, primes=primes):
        """
        Calculate a unique signature or perfect hash by multiplying prime
        numbers corresponding to each digit in a number.
        """
        sig = 1
        while num:
            sig *= primes[num % 10]
            num //= 10
        return sig

    for p1 in primes:
        p2 = p1 + 3330
        p3 = p1 + 6660
        if (p2 in primes_set and p3 in primes_set and
                anagram_hash(p1) == anagram_hash(p2) == anagram_hash(p3)):
            return f"{p1}{p2}{p3}"
예제 #25
0
def main():
    primes = [
        p for p in prime_sieve(10000)
        if p > 1000 and p not in {1487, 4817, 8147}
    ]
    primes_set = frozenset(primes)

    def anagram_hash(num, primes=primes):
        """
        Calculate a unique signature or perfect hash by multiplying prime
        numbers corresponding to each digit in a number.
        """
        sig = 1
        while num:
            sig *= primes[num % 10]
            num //= 10
        return sig

    for p1 in primes:
        p2 = p1 + 3330
        p3 = p1 + 6660
        if (p2 in primes_set and p3 in primes_set
                and anagram_hash(p1) == anagram_hash(p2) == anagram_hash(p3)):
            return f"{p1}{p2}{p3}"
예제 #26
0
def main():
    lim = 2000000
    return sum(prime_sieve(lim))
예제 #27
0
파일: 7.py 프로젝트: paamm/projectEuler
# Problem 7
"""By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.

What is the 10 001st prime number?"""

import utils

if __name__ == '__main__':
    # According to prime number theorem, the number of primes before the number n is,
    # #p ~= n/ln(n), which means that to find the 10,001st prime, we have n ~= 117000

    n = 117000
    primes = utils.prime_sieve(n)
    while len(primes) < 10001:
        n = int(n * 1.10)  # Increment by 10% until we have enough primes
        utils.prime_sieve(n)

    print(primes[10000])
예제 #28
0
파일: p108.py 프로젝트: icot/euler
import utils
from itertools import izip
import math


def main2():
    ndivs2 = 1998
    n2 = gennum(ndivs2)
    print math.sqrt(n2)


def gennum(ndivs):
    exps = utils.factors(ndivs)
    exps.reverse()
    exps = [exp - 1 for exp in exps]
    primes = utils.prime_sieve(100)
    g = izip(primes, exps)
    n = [pow(item[0], item[1]) for item in g]
    return reduce(lambda x, y: x * y, n)


def gen2(primes, limit):
    k = math.ceil(math.log(limit) / math.log(3))
    return k


if __name__ == "__main__":
    solutions = 4000000 * 4000000
    primes = utils.prime_sieve(1000)
    print gen2(primes, solutions)
예제 #29
0
import utils
import copy
"""
By replacing the 1st digit of the 2-digit number *3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.

By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit number is the first example having seven primes
among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993.
Consequently 56003, being the first member of this family, is the smallest prime with this property.

Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family.
"""

PRIMES = utils.prime_sieve(1000000, True)
P_MUTATED_MAP = {}


def insertAtAllLocs(digLocs, digits, prime):
    """Insert the mutated prime into the map as a new set, if it's not already a key,
    or append to the existing set if it is
    """
    for locs in digLocs:
        # all subsets of mutable locations
        mutableNum = copy.copy(digits)
        for l in locs:
            mutableNum[l] = "*"
        mutatedNum = utils.join(mutableNum, True)
        if mutatedNum in P_MUTATED_MAP:
            P_MUTATED_MAP[mutatedNum].add(prime)
        else:
            P_MUTATED_MAP[mutatedNum] = set([prime])
예제 #30
0
#!/usr/bin/env python3
"""Problem 12: Highly divisible triangular number"""

from functools import lru_cache, partial
from itertools import count

from utils import num_of_divisors, prime_sieve

num_of_divisors = lru_cache(maxsize=None)(partial(num_of_divisors,
                                                  primes=prime_sieve(1000)))


def main():
    for n in count(1):
        divisors = (num_of_divisors((n + 1) // 2) * num_of_divisors(n) if n
                    & 1 else num_of_divisors(n // 2) * num_of_divisors(n + 1))

        if divisors >= 500:
            return n * (n + 1) // 2


if __name__ == "__main__":
    print(main())
예제 #31
0
#!/usr/bin/env python
"""Problem 58: Spiral primes"""

from utils import prime_sieve
from math import sqrt

primes = prime_sieve(20000)
primes_set = set(primes)


def is_prime(n, primes=primes, primes_set=primes_set):

    if n in primes_set:
        return True

    max_divisor = int(sqrt(n))

    for prime in primes:
        if not n % prime:
            return False

        if prime > max_divisor:
            return True

    # all primes are of the form c#k + i for i < c# and i coprime to c#
    # let c = 6, c# = 2*3*5 = 30

    divisor = 19980

    while divisor <= max_divisor:
        if not (n % (divisor + 1) and n % (divisor + 7) and n %
예제 #32
0
def main():
    lim = 2000000
    return sum(prime_sieve(lim))
예제 #33
0
파일: p110.py 프로젝트: icot/euler
#!/usr/bin/python

from math import log, ceil, sqrt
from partitions import partitions_gen as partitions
from utils import prime_sieve

primes = prime_sieve(200)

def main():
    nsols = int(4000000)
    limit = 2 * nsols + 1
    K = ceil(log(2*nsols)/log(3))
    print K
    sols = {}
    for k in range(1,int(K)+2):
        pn = partitions(int(k)+1)
        candidates = {}
        for p in pn:
            contrib = [2*x +1 for x in p]
            ndivs = reduce(lambda x,y: x*y, contrib)
            candidates[ndivs] = (contrib, p)
        keys = candidates.keys()
        keys.sort()
        keys = [key for key in keys if key >= limit]
        if keys:
            key = keys[0]
            contrib, a = candidates[key]
            a.reverse()
            prods = [pow(pi, ai) for pi, ai in zip(primes, a)]
            num = reduce(lambda x, y: x * y, prods)
            print num, k, key, prods[:7], prods[-1]
예제 #34
0
# Problem 10
"""The sum of the primes below 10 is 2 + 3 + 5 + 7 = 17.

Find the sum of all the primes below two million."""

import utils

if __name__ == '__main__':
    primes = utils.prime_sieve(2000000)
    total = 0
    for prime in primes:
        total += prime
    print(total)
예제 #35
0
 def fn(self):
     sieve = prime_sieve(self.bound)
     sieve = [i for i, v in enumerate(sieve) if v]
     return sum(sieve)
예제 #36
0
 def fn(self):
     primes = prime_sieve(self.bound)
     primes = [i for i, v in enumerate(primes) if v][1:]
     bag = {i: self.terms(i) for i in primes if i is not 2 and i is not 5}
     return max(bag, key=bag.get)
예제 #37
0
 def fn(self):
     sieve = prime_sieve(self.limit)
     sieve = [i for i, v in enumerate(sieve) if v]
     return sieve[self.bound]
예제 #38
0
파일: 69.py 프로젝트: JJTimmons/euler
import utils
"""
Euler's Totient function, q(n) [sometimes called the phi function], is used to determine the number of numbers less than n which are relatively prime to n.
For example, as 1, 2, 4, 5, 7, and 8, are all less than nine and relatively prime to nine, q(9)=6.

It can be seen that n=6 produces a maximum n/q(n) for n <= 10.

Find the value of n <= 1,000,000 for which n/q(n) is a maximum.
"""

PRIME_LIST = utils.prime_sieve(1000000, as_list=True)
FACTOR_MAP = utils.gen_factor_map()


def phi(k):
    """
        return the number of relative primes
        number of ints, n, from 1 <= n_i <= k, where GCD(i, n) == 1
    """
    """
        Misc notes used in dev:
        3 % 3 -> 3 - 1

        4 % 2 -> 2. 4 - 2

        10 % 2 -> 5. 10 - 5
        5 % 5 -> 5 - 1

        30 / 2 -> 15. 30 - 15
        15 / 3 -> 5. 15 - 5
        10 / 5 -> 1. 10 - 2