PS U:\Projects\Cpp\Cui> .\Test.exe
*
**
***
****
*****
*
**
***
****
*****
PS U:\Projects\Cpp\Cui>
*
**
***
****
*****
*
**
***
****
*****
PS U:\Projects\Cpp\Cui>
このような図形表示の問題では「各行に何文字出力するか」を考えると問題が複雑になることが多くあります。出力する文字数自体はどの行も固定で、何も図形を表示したくない場所には半角空白を出力する方が簡単です。この場合、「それぞれの場所に出力すべき文字は空白か*か」を考えれば済むことになります。
今回の課題では出力する行数は10行、桁数は5文字です。
*と空白のどちらを出力するか判定するところは複雑なので、とりあえず三角形1個分だけを考えてプログラムを書いておき、一度動かしてから調整します。図形が複雑な場合、とりあえず同じような形の図形を出力するプログラムを作っておき、少しずつ修正していくことも大事です。
それぞれ、y行x桁(y=0〜4, x=0〜4)に*と空白のどちらを出力するべきか考えるわけですが、下のように表にしてみました。*を出力する条件は、いずれもx<=yであることが分かります。
| y | *の出力条件 |
|---|---|
| 0行目(y=0) | x<=0のとき |
| 1行目(y=1) | x<=1のとき |
| 2行目(y=2) | x<=2のとき |
| 3行目(y=3) | x<=3のとき |
| 4行目(y=4) | x<=4のとき |
まとめると次のようになります。
- 10行出力する。
- 各行に5文字ずつ出力する。
- 出力する文字は、x<=yであれば*、それ以外は空白。
ここまでの段階で、次のプログラムができます。
#include <stdio.h>
int main(void)
{
int x,y;
for(y=0; y<10; y++)
{
for(x=0; x<5; x++)
{
if(x<=y) printf("*");
else printf(" ");
}
printf("\n");
}
return 0;
}これを実行した結果は次の通りです。
PS U:\Projects\Cpp\Cui> .\Test.exe
*
**
***
****
*****
*****
*****
*****
*****
*****
PS U:\Projects\Cpp\Cui>
*
**
***
****
*****
*****
*****
*****
*****
*****
PS U:\Projects\Cpp\Cui>
一見すると正しく出力されていないように見えますが、最初の三角形(先頭5行分)は問題なく出力されています。*を出力する条件はx<=yなので、この条件式のみで考えれば10×10サイズの大きな三角形になりますが、各行5文字しか出力しないので右半分が切り取られたような形になっています。
さて、先ほどの表と同様にy=5〜9における*の出力条件を見てみます。
| y | *の出力条件 |
|---|---|
| 5行目(y=5) | x<=0のとき |
| 6行目(y=6) | x<=1のとき |
| 7行目(y=7) | x<=2のとき |
| 8行目(y=8) | x<=3のとき |
| 9行目(y=9) | x<=4のとき |
これを見ると、y>=5ではx<=y-5のときに*を出力すれば良いことが分かります。ただし、ここでいきなり次のように書くのはあまり賢いやり方ではありません。
if(y<5 && x<=y || y>=5 && x<=y-5) printf("*");
else printf(" ");このように書くと、「次は三角形を3個表示しよう」とか「10個表示しよう」などとプログラムを拡張したくなったときに融通が利きません。それどころか、だんだん条件文が長くなってしまいます。
ここは、もう少し考えて法則を見つけるのが賢明です。三角形3個目は次のような条件で出力します。
| y | *の出力条件 |
|---|---|
| 10行目(y=10) | x<=0のとき |
| 11行目(y=11) | x<=1のとき |
| 12行目(y=12) | x<=2のとき |
| 13行目(y=13) | x<=3のとき |
| 14行目(y=14) | x<=4のとき |
表の右側の列を見てほしいのですが、1個目の三角形も、2個目の三角形も、3個目の三角形も、右側の列が変わっていません。この時点で気付いてほしいのですが、yが5の倍数のときはx<=0が*の出力条件になっています。同様に、yが5の倍数+1のときはx<=1、yが5の倍数+2のときはx<=2……です。
要するに、
x<=(yを5で割った余り)
が*の出力条件なのです。余りを計算するのは%演算子ですから、*を出力する条件は
x<=y%5
です。これに従ってプログラムを書き換えてみましょう。さきほどのプログラムに「%5」の2文字を追加しただけです。
#include <stdio.h>
int main(void)
{
int x,y;
for(y=0; y<10; y++)
{
for(x=0; x<5; x++)
{
if(x<=y%5) printf("*");
else printf(" ");
}
printf("\n");
}
return 0;
}実行結果は次の通りになります。
PS U:\Projects\Cpp\Cui> .\Test.exe
*
**
***
****
*****
*
**
***
****
*****
PS U:\Projects\Cpp\Cui>
*
**
***
****
*****
*
**
***
****
*****
PS U:\Projects\Cpp\Cui>
最初に作ろうとしていた図形が出力されました。
今回のように、図形の問題で、しかも何かしらの繰り返しのパターンがある場合は % を使って割り算の余りを求めると、うまく解決できる場合が多いので覚えておくと良いかもしれません。


