(DAY3) 俺と学ぶRust言語~FizzBuzz~

## 今日の内容
- FizzBuzz？なにそれ
- C言語とRustでFizzBuzz問題に挑戦しよう
- ループ処理
- 条件分岐処理

# はじめに
[前回](https://qiita.com/FUKAch/items/8ff0dca6e22d27ad030c)は画面出力について学びました。今回はFizz Buzz問題に挑戦したいと思います。
**Fizz Buzz**とは、「1」から順に数字を発言していき、その数字が3の倍数であれば代わりに「Fizz」と、5の倍数であれば「Buzz」と、3の倍数かつ5の倍数であれば代わりに「FizzBuzz」と発言するというゲームです。
そして、このゲームをコンピュータに表示させることができるかどうかで、その人がプログラムを書けるかどうかを判断する、という問題が **『Fizz Buzz問題』** です。
初心者専用の問題に見えますが、実は縛りを追加することで上級者も悩める問題となっています。

# Fizz! Buzz! FizzBuzz!!!!!!
さっそくFizz Buzz問題に挑んでみましょう。
基本的には1から順に数字を出力すればよいですね。まずはそのプログラムを書いてみます。
C言語では以下のようになります。無限に出力するわけにはいかないので、15まで表示させています。
```c
#include <stdio.h>
int main(){
    int i;
    for(i=1; i<=15; i++) printf("%d ", i);
    return 0;
}
/******** 出力結果 *******
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
*************************/
```
for文を使っています。1から任意の数字までに対応できるよう、ループ処理を行っています。ループ処理について全く知らない方は[「ループ処理とは」](https://wa3.i-3-i.info/word15414.html)から学んでください。
C言語ではループ処理として主にfor文、while文、do-while文があります。他に思いつくのはgotoでしょうか..。
Rustでも同じようにループ処理を用いて解きます。
```rust
fn main(){
    for i in 1..16 {
        print!("{} ", i);
    }
}
/******** 出力結果 *******
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
*************************/
```
同じくfor文を使いました。ではさっそくfor文について学ぼう...と言いたいところですが、その思考をいったん放置してください。とりあえず完成させて、部分にわけて解説していきます。というわけで、完成品がこちらです。
[エスケープシーケンス](https://wa3.i-3-i.info/word11732.html)を利用して、1出力ごとに改行して表示しています。
```c
/*C言語*/
#include <stdio.h>
int main(){
    int i;
    for(i=1; i<=15; i++){
        if(i % 15 == 0) printf("FizzBuzz\n");
        else if(i % 3 == 0) printf("Fizz\n");
        else if(i % 5 == 0) printf("Buzz\n");
        else printf("%d\n", i);
    }
    return 0;
}
/******** 出力結果 *******
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

*************************/
```
```rust
/*Rust*/
fn main(){
    for i in 1..16 {
        if i % 15 == 0 {println!("FizzBuzz");}
        else if i % 3 == 0 {println!("Fizz");}
        else if i % 5 == 0 {println!("Buzz");}
        else {println!("{}", i);}
    }
}
/******** 出力結果 *******
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz

*************************/
```
それでは解説していきます。まず、main関数があります。これは別名「エントリーポイント」と呼ばれ、プログラムの一番最初に実行される場所を指します。~~C言語やRustなどのコンパイル型言語は通常main関数がエントリーポイントとなっているため、main関数は必須になります。ただし、言語によってmain関数の定義形式が変わります。~~ Rustでは関数の定義が「fn 関数名(引数){中身}」となっているため、main関数は「fn main(){}」と定義します。

次に、for文です。すでに触れていますが、for文はループ処理の一つです。他にはwhile文やloop文があります。ループ処理にいくつか種類があるのには、ループの仕方に違いがあって、それを使い分けるためです。
例えば、「n回繰り返したい」ならfor文、「この条件式が成り立つ間繰り返したい」ならwhile文、「無限に繰り返したい」ならloop文などです。
今回は「15回繰り返したい」ので、for文を使うことにします。(注：loopやwhileでもできます。)for文の文法は、「for 変数 in 最初の値..最後の値+1 {中身}」となります。例えば、変数「i」が、i=1で始まって、i<16であれば「中身」を実行し、i=i+1する、を繰り返すといった感じです。そうすると、i=i+1 =16となったとき、i<16ではないので、「中身」が実行されず、結果的に「中身」は15回繰り返された..ということになります。

次に、if-else文です。if-else文は条件分岐処理の一つです。「条件分岐処理」について全く知らない方は[「条件分岐処理とは」](https://wa3.i-3-i.info/word15415.html)から学んでください。Rustでは、if-elseやmatchなどの条件分岐処理が用意されています。matchはC言語でのswitchに似ています。
基本的な条件分岐はif-else文で行います。「もし、この条件が真なら、この処理を行う。もし偽なら、この処理を行う」といったようなことができます。「真」と「偽」は「正しい」、「正しくない」もとい、「true」、「false」を意味します。
プログラムを見てみると、for文の中身は4行になっていますが、この4行全てが条件分岐処理になっています。上から、
「もし変数が15で割り切れるなら、"FizzBuzz"と表示する。」
「でなければ、もし変数が3で割り切れるなら、"Fizz"と表示する。」
「でなければ、もし変数が5で割り切れるなら、"Buzz"と表示する。」
「でなければ、変数を表示する。」
という意味になっています。ここでの「変数」は、for文の「変数」と同じものです。つまり、for文で変数「i」が1,2,3,4,..と増加するとき、もし変数「i」が15で割り切れるなら、"FizzBuzz"と表示する。といった感じになります。割り切れるかは[剰余演算（%）](https://wa3.i-3-i.info/word15339.html)を用いて計算します。if-else文の文法は、「if 条件式1 {中身}」、「else if 条件式2 {中身}」、「else {中身}」となります。順番に、「もし～なら」、「でなければ、もし～なら」、「そのどれでもないなら」となります。「else」で始まるものは、直前に「if 条件式1 {中身}」がなくてはなりません。

これで解説を終わります。

# おわりに
おつかれさまでした。今回は、100DaysOfCode 三日目として、Fizz Buzz問題に挑戦してみました。
明日はfor文についてより詳しく学んでいきます。
ご精読、ありがとうございました。

# おまけ
筆者が頑張って一行縛りでfizzbuzz問題に挑戦してみました。とは言っても、三項演算子がなくてブルブルしながら書いた粗悪品です...。あと!(i%15)とかもエラー出て感動しました。
```rust
fn main(){
    for i in 1..16{println!("{v}",v= if i%15==0 { "FizzBuzz".to_string() } else if i%3==0 { "Fizz".to_string()} else if i%5==0 { "Buzz".to_string()}else { i.to_string()});}
}
/******** 出力結果 *******
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
*************************/
```