It's possible to do with two (or 1, with a helper function) loops, nested. Oh, and some math.
Consider that we can write a function really easily to print a row.
void print_row(char ch, int len) {
for (int i = 0; i < len; i++) {
std::cout << ch;
}
std::cout << std::endl;
}
If we call that we only need 1 loop. If we loop to a certain size, we really need to go to size times 2 minus 1. What number is generated each time?
const int size = 4;
for (int i = 1; i <= size * 2 - 1; i++) {
...
}
1
2
3
4
5
6
7
What we really need are these numbers, though, to give to print_row
:
1
2
3
4
3
2
1
Up until we get to 5, it's all good. For 5 and above, we need to get back to lower numbers. We can use a ternary operator and some math to get there.
const int size = 4;
for (int i = 1; i <= size * 2 - 1; i++) {
int len_of_row = (i <= size ? i : size - (i - size));
print_row('0', len_of_row);
}
Let's pick that apart. i - size
when i
is 5 and size
is 4 will give us 1
. If we subtract that from our size
, we get 3
. If we do the same with i
being 6
, we get 2
, and if we do it with 7
we get 1
.
Now, maybe the ternary is a cheat because it's a replacement for a conditional.
We can eliminate the ternary expression by taking advantage of operator precendence and how boolean logic short-circuits. We do have to rewrite print_row
turn return bool
and always return true
.
const int size = 4;
for (int i = 1; i <= size * 2 - 1; i++) {
i <= size && print_row('0', i) || print_row('0', size - (i - size);
}