Esempio n. 1
0
def ans():
    max_p = 10**8
    primes = sieve_primes(max_p)
    res = 0
    for p in tqdm(primes[2:]):  # skip 2,3
        res += s(int(p))
    return res
Esempio n. 2
0
def ans():
    max_n = 4 * 10 ** 7
    primes = sieve_primes(max_n)
    totient_of_all = totient_euler_range(max_n, primes=primes)
    d = {i: totient_chain_length(i, totient_of_all) for i in primes}
    wanted_chain_length = 25
    return sum([p for p, v in d.items() if v == wanted_chain_length])
Esempio n. 3
0
def ans():
    max_n = 10**8
    primes = sieve_primes(max_n // 2)
    s = 0
    primes_to_iterate = primes[:np.searchsorted(primes, math.sqrt(max_n))]
    for i, p in tqdm(enumerate(primes_to_iterate)):
        less = np.searchsorted(primes, max_n / p)
        s += less - i
        primes = primes[:less + 1]
    return s
Esempio n. 4
0
def ans():
    max_n = 10**7
    primes = sieve_primes(max_n)
    primes_sqrt = primes[:np.searchsorted(primes, sqrt(max_n)) + 1]
    s = 0
    for i, p in enumerate(primes_sqrt):
        primes_to_iterate = primes[i + 1:np.searchsorted(primes, max_n // p) +
                                   1]
        for q in primes_to_iterate:
            s += m(p, q, max_n)
    return s
Esempio n. 5
0
def ans():
    """
    The idea:
    First, get a list of all primes in the range (1,n).
    Then we want to generate co-prime groups in a smart way,
    that minimizes the number of groups that are for sure worse than other groups.

    First, for each pair of primes (sorted),
    check if their product is still less than n - if merging them is even valid,
    and if the sum of the max possible values out of each of them is less than
    the max possible num from these factors that is still <=n, which means that merging them increases the sum.
    Obviously, if their product is bigger than n, we can stop the inner loop, and this can be optimized even more
    by checking if this was the first inner iteration, and if so, we can stop the outer loop.
    For each merged pair we keep the profit of the merging (in a dict):
    (the max value of these factors that is <= n) minus (the sum of the max possible values out of each of them)
    Do the same for triples, checking whether the max value for merging all 3 of them is better than any other
    combination of sums.
    We can basically do this generically for any lengths tuples, but i could not figure out how to do this
    without messing with nasty combinatorics, so i created thee same process for quads,
    which resulted in 0 improving quads, so i knew that we only need size 2,3 and not more than that.
    The code for quads is still in the solution file but i dont use it because it is a waste of run time.
    NOTE: running for 2*10**6, i found that there are indeed ~20 numbers that come from quads, so my solution is NOT
    generic, and who knows, maybe there are even pentas for a very large n value. But this is not the problem here.

    Now we have a group of values (the dict values) that we should take a subgroup of it with the biggest sum possible,
    such that there are no two chosen values that their keys share a number.
    This is a classic Linear Programming problem.
    Define:
        variables: each of the values should get a variable that is a boolean bi - chosen or not
        optimization: optimize the sum of vi*bi
        restrictions: no 2 values with a shared prime factors should both be chosen
    NOTE: the whole problem could have been solved using this approach, but the preprocessing reduces the complexity
    of the LP problem by A LOT

    At the end, combine the result of the LP model with the base value of the max power of each prime,
    and dont forget to add 1 as it is not a part of any prime calculation!

    Optimization result:
    only 4654 primes out of 17984 used to improve.
    only 21218 total numbers in LP out of 200000.
    """
    n = 2 * 10**5
    primes: List[int] = sieve_primes(n)
    data = improving_tuples(n, primes)
    res = linear_programming_sol(data)
    return res
Esempio n. 6
0
def ans():
    max_n = 10**6
    primes = sieve_primes(max_n)
    # for (2,3)-> 12, for (3,5)-> no solution, start from (5,7):
    primes = [int(p) for p in primes[2:]]
    # add one more prime because the given limit is for p1
    primes.append(nextprime(primes[-1]))
    s_sum = 0
    for p1, p2 in zip(primes, primes[1:]):
        """
        let tp = 10**(number of digits of p1)
        so we want smallest s s.t.:
        s = k * tp + p1, and s % p2 = 0
        ->
        k * tp = -p1 (mod p2)
        k * tp = p2 - p1 (mod p2)
        k = (tp ^ -1) * (p2 - p1)  (mod p2)
        """
        power_10 = 10**num_size(p1)
        k = (inverse_mod(power_10, p2) * (p2 - p1)) % p2
        s = k * power_10 + p1
        s_sum += s
    return s_sum