First of all, the people telling you that you can't solve this problem with brute force in under a minute are wrong. A brute force algorithm for a problem this size will run in a few seconds.
Second, the code that you posted has several problems, some of them already mentioned.
- You should terminate the loop by setting
one to some value other than 0 once you reach your goal condition (where you currently print a).
- You never reinitialize the list (
l = []). This should be done each time you recalculate a and b, right before you enter the for loop.
- The question asks for the first triangle number to have over five hundred divisors. Your condition for termination should be
if len(l) > 500:.
- Your probably don't want to
print a inside the for loop, but wait until the while loop is done.
The thing that's really slowing you down is that for each triangle number a you're checking every value up to a / 2 to see if it's a divisor. Your only need to check values up to the square root of a. This way for each value of x, if x is a divisor you can just add x and a / x to the list.
Here's your code with the modifications I outlined above:
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()
You'll see that it runs in about 5 or 6 seconds, so well under a minute with these modifications.
while 1or at leastwhile 1==1? Couldn't the variable be calledrunningor something?