简体   繁体   中英

How to make my program more efficient in Python

So I had to make a code which generates the first triangle number which has over 500 factors. The problem is given in detail below:

The sequence of triangle numbers is generated by adding the natural numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28. The first ten terms would be:

1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...

Let us list the factors of the first seven triangle numbers:

1: 1 3: 1,3 6: 1,2,3,6 10: 1,2,5,10 15: 1,3,5,15 21: 1,3,7,21 28: 1,2,4,7,14,28 We can see that 28 is the first triangle number to have over five divisors.

What is the value of the first triangle number to have over five hundred divisors?

I have written a block of code which generates the same however it is highly inefficient ; kindly suggest some ways to improve it. Moreover it is so inefficient that it only works with numbers below 70

My code is given below, please refer:

def generates_triangle_numbers_upto_n(n):
    list = [1]
    while len(list)<n:
        nth = int(len(list)+1)
        to_be_appended = nth/2 + nth**2/2
        list.append(to_be_appended)
    return list

def return_number_of_n(n):
    num = 0
    for i in range(2, int(n)):
        if n%i == 0:
            num = num+1
    return num + 2

def main(n):
    list = generates_triangle_numbers_upto_n(20000)
    for i in list:
        if return_number_of_n(i) >  int(n):
            return i

print(main(100))

I saw a similar question on this site but I didn't understand how it worked:

Thanks a lot!

Edit 1: Thanks everyone for the wonderful suggestions, based on which I have refined my code:

def main(n):
    list = [1]
    while return_number_of_n_second(list[len(list)-1]) <= n:
        nth = int(len(list)+1)
        to_be_appended = int(nth/2 + nth**2/2)
        list.append(to_be_appended)
    return list[len(list)-1]

def return_number_of_n_second(n):
    num = 0
    import math
    sqrt = math.sqrt(n) 
    for i in range(2, math.ceil(math.sqrt(n))):
    if n%i == 0:
        num = num+1
    if int(sqrt) == sqrt:
        return num*2 +3
    return num*2 + 2

print(main(500))

However, now too, it takes 10-15 seconds to execute. Is there a way to make it even more efficient since almost all of project euler's problems are to be executed in 2-3 seconds max?

Just some basic technical optimizations and it should do it:

import time
import math


def main(n):
    last, length = 1, 1

    while return_number_of_n_second(last) <= n:
        length += 1
        last = int(length/2 * (length+1))

    return last


def return_number_of_n_second(n):
    sqrt = math.sqrt(n)
    if int(sqrt) == sqrt:
        return 2
    return sum(1 for i in range(2, math.ceil(sqrt)) if not n % i) * 2 + 2

start_time = time.time()
print(main(500))
print(time.time() - start_time)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM