There's the hard way (using 5 different variables), and there's the easy way (using a buffer and three variables).
This has "nested loops" and counts up and down, and indents appropriately.
#include <stdio.h>
int main() {
char buf[ 128 ], *at;
int r, i;
int lftBlnk = 32;
for( r = 1; r <= 256; r *= 2 ) {
at = buf;
for( i = 1; i <= r; i *= 2 ) // ascending
at += sprintf( at, "%-4d", i );
for( i /= 4; i; i /= 2 ) // descending
at += sprintf( at, "%-4d", i );
printf( "%*s%s\n", lftBlnk, "", buf ); // indent & output
lftBlnk -= 4;
}
return 0;
}
Output
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 256 128 64 32 16 8 4 2 1
EDIT:
Having some fun, stripping out what's unnecessary, the code reduces to be quite compact.
int main() {
for( int lftBlnk = 32, r = 1; r <= 256; r *= 2, lftBlnk -= 4 ) {
printf( "%*s", lftBlnk, "");
int i;
for( i = 1; i <= r; i *= 2 ) printf( "%-4d", i );
for( i /= 4; i; i /= 2 ) printf( "%-4d", i );
putchar( '\n' );
}
return 0;
}
In fact, let's get rid of a variable, add another, and improve the flexibility of the code (without repeated constants like '4' and magic numbers like 256.) Now, specify the no. of rows, and allow enough width for each column...
int main() {
int rows = 11, wid = 5;
for( int r = 0; r < rows; r++ ) {
printf( "%*s", (rows-1-r)*wid, "");
int i;
for( i = 1; i <= (1 << r); i *= 2 ) printf( "%-*d", wid, i );
for( i /= 4; i; i /= 2 ) printf( "%-*d", wid, i );
putchar( '\n' );
}
return 0;
}
1
1 2 1
1 2 4 2 1
1 2 4 8 4 2 1
1 2 4 8 16 8 4 2 1
1 2 4 8 16 32 16 8 4 2 1
1 2 4 8 16 32 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 256 128 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 256 512 256 128 64 32 16 8 4 2 1
1 2 4 8 16 32 64 128 256 512 1024 512 256 128 64 32 16 8 4 2 1