Прежде всего, люди, которые говорят вам, что вы не можете решить эту проблему грубой силой за минуту, ошибаются. Алгоритм грубой силы для задачи такого размера будет запущен через несколько секунд.
Во-вторых, код, который вы опубликовали, имеет несколько проблем, некоторые из них уже упомянуты.
- Вы должны прекратить цикл, установив для
one
какое-либо значение, отличное от 0
, как только вы достигнете своего целевого состояния (где вы в настоящее время print a
).
- Вы никогда не будете повторно инициализировать список (
l = []
). Это следует делать каждый раз, когда вы пересчитываете a
и b
, прямо перед входом в цикл for.
- Вопрос требует, чтобы у первого числа треугольника было над пятью сотнями делителей. Ваше условие для прекращения должно быть
if len(l) > 500:
.
- Вы, вероятно, не хотите
print a
внутри цикла for, но подождите, пока цикл while не будет завершен.
То, что действительно замедляет вас, это то, что для каждого номера треугольника a
вы проверяете каждое значение до a / 2
, чтобы увидеть, является ли это делителем. Вам нужно только проверить значения до квадратного корня из a
. Таким образом, для каждого значения x
, если x
является делителем, вы можете просто добавить x
и a / x
в список.
Вот ваш код с изменениями, которые я описал выше:
import math
def main():
l = []
one = 0
a = 1
b = 2
while one == 0:
a = a + b
b += 1
l = []
sqrt_a = int(math.sqrt(a))
for x in range(1, sqrt_a + 1):
if a % x == 0:
l.append(x)
if x < math.sqrt(a):
l.append(a // x)
if len(l) > 500:
# print(a)
one = 1
print(a, b, len(l))
if __name__ == '__main__':
main()
Вы увидите, что он запускается примерно через 5 или 6 секунд, что намного меньше минуты с этими изменениями.