Search code examples
pythonwhile-looptriangular

Can't get out of While loop(Python 3.9)


I'm a new at programming, I like solving this euler questions and I know there are solutions for this problem but it's not about the problem at all actually.

enter image description here

So, i managed to create a working function for finding example: 33. triangular number. It works but i couldn't manage to properly desing my while loop. I wanted to make it like, it starts from first triangular checks it's divisors make list of it's divisors, checks the length of the divisors, because problem wants "What is the value of the first triangle number to have over five hundred divisors?" . But i never managed to work the while loop. Thank you for reading.

nums = [1]
triangles = [1]
divisors = []

def triangularcreator(x):
    if x == 1:
        return 1
    n = 1
    sum = 0
    while n!=0:
        n += 1
        nums.append(n)
        for i in range(len(nums)):
            sum += nums[i]
        triangles.append(sum)
        sum = 0
        if x == len(triangles):
            n = 0
    return triangles[-1]


counter = 1
while True:
    for i in range(1, triangularcreator(counter) + 1):
        if triangularcreator(counter) % i == 0:
            divisors.append(i)
    if len(divisors) == 500:
        print(triangularcreator(counter))
        break
    counter +=1
    divisors.clear()

Solution

  • You should try to change a few things, starting with calculating just once the value of triangularcreator(counter) and assigning this value to a variable that you can use in different points of your code.

    Second, you create a loop which will be calculate always triangularcreator(1). At the end of each iteration you increase the value of counter+=1, but then at the beginign of the new iteration you assignt it again value 1, so it will not progress as you expect. Try this few things:

    counter = 1
    
    while True: 
        triangle = triangularcreator(counter)
        for i in range(1, triangle  + 1):
            if triangle  % i == 0:
                divisors.append(i)
        if len(divisors) == 500:
            print(triangle )
            break
        counter +=1
    

    Also these two arrays nums = [1], triangles = [1] should be declared and initialized inside the def triangularcreator. Otherwise you would be appending elements in each iteration

    Edit: I believe it is better to give you my own answer to the problem, since you are doing some expensive operations which will make code to run for a long time. Try this solution:

    import numpy as np
    
    factor_num = 0
    n = 0
    
    def factors(n):
        cnt = 0
        # You dont need to iterate through all the numbers from 1 to n
        # Just to the sqrt, and multiply by two. 
        for i in range(1,int(np.sqrt(n)+1)):
            if n % i == 0:
                cnt += 1
        # If n is perfect square, it will exist a middle number
        if (np.sqrt(n)).is_integer():
          return (cnt*2)-1
        else:
          return (cnt*2)-1
    
    while factor_num < 500:
        # Here you generate the triangle, by summing all elements from 1 to n
        triangle = sum(list(range(n)))
        # Here you calculate the number of factors of the triangle
        factor_num = factors(triangle)
        n += 1
    
    print(triangle)