Creating number pattern (triangle numbers) in C++ with minimum loops We were asked to make a triangular number pattern in C++ with minimum loops:


____1_____
___2__3____
__4__5__6__
7__8__9__10



Code:

#include &lt;iostream&gt;

using namespace std;
int main() {
    int n=0, r=0, i=0;
    cout &lt;&lt; "No. of rows: ";
    cin &gt;&gt; r;

    for( n=1; n&lt;=r; n++) {
        for( i=1; i&lt;=r-n; i++) {
            cout &lt;&lt; "  ";
        }
        for( i=(n*(n-1)/2)+1; i&lt;=(n*(n+1)/2); i++ ) {
            if( i&lt;10 )
                cout &lt;&lt; " " &lt;&lt; i &lt;&lt; "  ";
            else
                cout &lt;&lt; i &lt;&lt; "  ";
        }
        cout &lt;&lt; "\n";
    }
    return 0;
}


Output:



Here's what I'd like reviewed:


Is it wise to use pattern-generating formulas? For example, for putting value of i in the last loop, I used the formula for the pattern \$1,2,4,7\$... as \$\frac{n*(n-1)}{2}+1\$. Is it efficient? This involves four operations in each iteration, and it's fairly slow.
Is it possible to reduce the number of loops? Is it better to reduce variables or reduce loops?
Spacing

Use as much whitespace as needed, it makes it easier to read code, especially formulas or expressions with a lot of operators.



using namespace std;


This is discouraged, I don't think it makes much difference in a program of this size, but it can be a bad habit to rely on.



int n=0, r=0, i=0;


Try and only declare variables in the smallest scope possible, as in right when you need them. Since n and i are only ever used inside the loops, only declare them there. 

I would avoid assigning 0 to r, as then if later the program crashes, and I see r no value, it makes the bug much easier to spot than if r has a valid value.



for( n=1; n&lt;=r; n++) {
    for( i=1; i&lt;=r-n; i++) {
        cout &lt;&lt; "  ";
    }


This is completely up to you, but I would start the loops at 0, and go until n &lt; r or i &lt; r-n. That is because I would consider that a standard loop, and it is very quick to see how many times it loops, what stopping condition is, and what it loops over. I understand why you are starting from 1, the number of rows, but since this is never actually used, an off by one error wouldn't actually be noticeable. It is barely worth thinking about, but if you are writing for loops over and over, it makes it easier to read. Take this with a grain of salt.



for( i=(n*(n-1)/2)+1; i&lt;=(n*(n+1)/2); i++ ) {


As we are printing out the natural numbers, starting from 1, and going to r*(r+1)/2, I would just have a variable that keeps counting upwards. Then I don't have to work out what number the row starts with each time, and you are incrementing i anyway, so there is essentially no extra work done by having a count, and you save a few operations too.



    if( i&lt;10 )
        cout &lt;&lt; " " &lt;&lt; i &lt;&lt; "  ";
    else
        cout &lt;&lt; i &lt;&lt; "  ";
}


This is exactly what padding was made for. I don't really know how to pad with cout, but printf makes it very easy. It looks like:

printf("%*d in the bed, and the little one said %s", the_amount_of_spaces, the_number_to_print, "a_piece_of_inpsiring_text");


Where everything inside the quotes is what to print, % means the next piece is a variable, %d means an int, %s means a string

There are some other things you can do, like if you never want to change the number of spaces, you can hardcode it like: 
    printf("%3d ", count);

Here is a reference for it



Below are all the changes I would make thrown together, if you have any questions, ask away


   
#include &lt;iostream&gt;
#include &lt;stdio.h&gt;

int main() {
    int r;
    std::cout &lt;&lt; "No. of rows: ";
    std::cin >> r;

    int count = 1;
    for(int n = 1; n &lt;= r; n++) {
        for(int i = 0; i &lt; r - n; i++) {
            std::cout &lt;&lt; "  ";
        }

        while(count &lt;= (n*(n + 1)/2)) {
            printf("%3d ", count);
            count++;
        }
        std::cout &lt;&lt; "\n";
    }
    return 0;
}


The padding works well up until 45 rows are entered, after that, it was too wide for my screen to properly read.