Сумма чисел от 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()