Дан список цифр от 1 до n найти умножение двух элементов равное сумме списка без этих двух элементов? Как ускорить код?

Рейтинг: 1Ответов: 1Опубликовано: 06.06.2023
def remov_nb(n):
    l1 = []
    l = list(range(1, n+1))
    for x in l:
        i = 1
        while i < len(l):
            if sum(l)-x-l[i] == x *l[i]:
                l2=(x, l[i])
                l1.append(l2)
                i+=1
            else:
                i += 1

    return l1

Ответы

▲ 5Принят

Сумма чисел от 1 до n равна n(n + 1)/2. Обозначим её s.

Нужно найти a и b такие что s - a - b = ab, 1 ≤ a < b ≤ n.

Вынесем b: s - a = (a + 1)b. В итоге b = (s - a) / (a + 1).

Список не нужен, внутренний while тоже. Перебор по всем a. b вычисляется:

def solve(n):
    s = n * (n + 1) // 2
    for a in range(1, n + 1):
        if (s - a) % (a + 1) == 0:
            b = (s - a) // (a + 1)
            if a < b <= n:
                yield a, b


def main():
    n = 1
    while True:
        answer = tuple(solve(n))
        if answer:
            print(n, answer)
        n += 1


main()

Дальше. b должно быть целое. То есть (s - a) ⫶ (a + 1), что равносильно (s - a + a + 1) ⫶ (a + 1). Получаем (s + 1) ⫶ (a + 1). Вместо перебора всех а можно перебрать делители s + 1, что быстрее.

import math


def factors(n):
    i = 2
    j = n
    j_sqrt = math.isqrt(j)
    while i <= j_sqrt:
        if j % i == 0:
            p = 0
            while j % i == 0:
                j //= i
                p += 1
            yield i, p
            j_sqrt = math.isqrt(j)
        i += 1 if i == 2 else 2
    if j > 1:
        yield j, 1


def divisors(n):
    f = tuple(factors(n))

    def search(i):
        if i == len(f):
            yield 1
            return
        p, e = f[i]
        for d in search(i + 1):
            yield d
            for _ in range(e):
                d *= p
                yield d

    yield from search(0)


def solve(n):
    s = n * (n + 1) // 2
    for d in divisors(s + 1):
        a = d - 1
        if 1 <= a < n:
            assert (s - a) % (a + 1) == 0
            b = (s - a) // (a + 1)
            if a < b <= n:
                yield a, b


def main():
    n = 1
    while True:
        answer = tuple(sorted(solve(n)))
        if answer:
            print(n, answer)
        n += 1


main()