patternpythonModerate
Finding two consecutive triangular numbers with a given target sum
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:
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:
continueSolution
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:
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
doesn’t roll off the tongue as nicely, but it’s never going to be confused for getting triangular numbers, and the
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.
-
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 FalseWe’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 likedef 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 Falsedef is_consecutive_triangular_square_sum(n):Context
StackExchange Code Review Q#125440, answer score: 16
Revisions (0)
No revisions yet.