HiveBrain v1.2.0
Get Started
← Back to all entries
patternpythonModerate

Finding two consecutive triangular numbers with a given target sum

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
sumtargetwithnumberstwofindinggivenconsecutivetriangular

Problem

I need to speed up this code so it can handle inputs in the thousands. It adds triangular numbers to a list based on input n, then it loops through to find if any two consecutive numbers squared in that list add up to n. The test cases I've been using are n = 45, which would be true and n = 6, which would be false.

Here is the code:

def Triangular(n):
    lst = []
    for i in range(1, n + 1):
        lst.append((i** 2 + i)//2)

    for i in lst:
        for j in lst:
            if i*i + j*j == n and ((lst.index(i) == lst.index(j)+1) 
                               or (lst.index(i) == lst.index(j)-1)):
                return True
            else:
                continue

Solution

A few suggestions:

-
Explicitly return False if the condition fails, i.e., if there aren’t two triangular numbers that sum to n.

As it stands, your function with either return True or None.

-
Don’t store the first n triangular numbers in a list; check them as you go through.

For large n, you’ll be creating a very large list, which will slow down Python. And the vast majority of the numbers in that list will be greater than n, so cannot possibly sum with a consecutive triangular number squared to give n.

This is much more efficient:

for i in range(1, n + 1):
    # If T_1 = i (i+1) / 2 and T_2 = (i+1) (i+2) / 2 then
    # we have
    # T_1^2 + T_2^2 = (i+1)^2 [i^2 + (i+2)^2] / 4
    result = (i+1)**2 * (i**2 + (i+2)**2) / 4
    if result == n:
        return True
    elif result > n:
        return False


We’re not storing lots of numbers in a list, and we’re only going until it’s impossible to find a working combination.

On my fairly weedy old laptop, this can take O(10^7) input and finish in under a second.

-
Use a better function name, and write a docstring.

Per PEP 8, function names in Python should be lowercase_with_underscores; your CamelCase function gives the impression of being a class.

And Triangular isn’t a very helpful name – if I saw that being called, I’d probably assume it was returning the nth triangular number. Something like

def is_consecutive_triangular_square_sum(n):


doesn’t roll off the tongue as nicely, but it’s never going to be confused for getting triangular numbers, and the is_ prefix suggests that it probably returns a boolean.

You should also write a docstring, which explains what the function is supposed to do. Useful for interactive help and/or people reading your code.

Code Snippets

for i in range(1, n + 1):
    # If T_1 = i (i+1) / 2 and T_2 = (i+1) (i+2) / 2 then
    # we have
    # T_1^2 + T_2^2 = (i+1)^2 [i^2 + (i+2)^2] / 4
    result = (i+1)**2 * (i**2 + (i+2)**2) / 4
    if result == n:
        return True
    elif result > n:
        return False
def is_consecutive_triangular_square_sum(n):

Context

StackExchange Code Review Q#125440, answer score: 16

Revisions (0)

No revisions yet.