1

A triangular number or triangle number counts objects arranged in an equilateral triangle. Their formula is n(n+1)/2.

I want to write a number as the sum of two triangular numbers. ( 24=21+3 ; 48=45+3 )

I have written some code in C++ that does this pretty well for smaller numbers. But as N gets bigger it becomes slower and slower, which makes me think my code is inefficient or downright wrong. So I am asking for suggestions.

I am open to and would appreciate any criticism or ideas you might have. Here's what I came up with.

It generates the number "i" and gives "j" the value of x-i. It tests if both the numbers are triangular (iok, jok) and if they are, it prints them out and ends. If it doesn't find such numbers, it prints "NO".

#include <iostream>

using namespace std;

int main(){
    long long x;
    cin>>x;
    long long j,i;
    int iok,jok;
    long sum;
    long long n;

    for(i=1;i<=x;i++){
        iok=0;
        sum=0;
        for (n=1; sum<=i; n++)
        {
            sum = sum + n;
            if (sum==i)
                iok=1;
        }
        j=x-i;
        jok=0;
        sum=0;
        for (n=1; sum<=j; n++)
        {
            sum = sum + n;
            if (sum==j)
                jok=1;
        }
        if(jok && iok){
            cout<<i<<" "<<j;
            return 0;
        }
    }
    cout<<"NO";
    return 0;
}

  • 1
    Off the top, you don't need to enumerate all `i` and then test whether `i` is triangular. You can loop over `n` and set `i = n*(n+1)/2`, so you only look at triangular numbers to begin with. They are very sparse, so you'll have many fewer iterations of the outer loop. Also, you can stop as soon as `i > x/2` – Igor Tandetnik Jan 04 '20 at 18:37
  • Why does the check for whether `j` is triangular loops until `sum<=i`? Shouldn't that be `sum<=j`? – Igor Tandetnik Jan 04 '20 at 18:40
  • Your algorithm has a time complexity of O(n^2) but you can solve the problem with one loop with complexity of O(n). Iterate over `n`, create the `n`-th triangular number, subtract it from from input and check if the result is a triangular number. – Thomas Sablik Jan 04 '20 at 18:41
  • 1
    I'm just curious. Did someone teach you to declare all variables at the beginning? It's a bad habit that I often see with beginners. Read: [ES.21: Don’t introduce a variable (or constant) before you need to use it](http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-introduce) – Thomas Sablik Jan 04 '20 at 18:44
  • @IgorTandetnik It should have been `sum<=j`, you are right, thanks! – T9 Ethereal Jan 04 '20 at 18:50
  • @ThomasSablik I'll give it a try, thank you! It is indeed a habit of mine to declare them at the start, but I didn't know it was a bad one. I just didn't find a better place for it and it feels somewhat right. – T9 Ethereal Jan 04 '20 at 18:53

1 Answers1

1

Your algorithm has a time complexity of O(n^2) but you can solve the problem with one loop with complexity of O(n). Iterate over n, create the n-th triangular number, subtract it from from input and check if the result is a triangular number. – Thomas Sablik

anatolyg
  • 26,506
  • 9
  • 60
  • 134