自分なりのFizzBuzzの解説。


エセコボラーがFizzBuzzを解説してみました。

# 材料

* 代数演算子
* 比較演算子
* 条件分岐
* 繰返し制御
* 順次、逐次
* 改行コード
* 数値型変数
* 変数のパース

# PHPでFizzBuzz問題を解いてみる。


問題の解決には、問題を分解することが重要。

これは実生活でも同じ。（知らんけど）

僕が初めて、SES契約で常駐した会社の常務さんは、
**「我々の仕事は、因数分解なんやで」** ってプロパーの社員さんに話してた気がする。
もう１４年前かな。

でもこの話は時間と共に、大きなインパクトを僕の中に植え付けた。（多分、多分）

***脱線を戻そう***


# 問題の分割をやってみよう。

* １〜１００までの数字を出力
* ３の倍数はFizzを出力
* 5の倍数はBuzzを出力
* 3の倍数と5の倍数の場合FizzBuzzを出力

これら４つが分割結果。

# １〜１００までの数字を出力しよう。

```php
<?php
for($i=1;$i<=100;$i++){
    echo $i;
}
```

結果は↓となった。

```
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
```

## Try and Error

僕の人生はトライアンドエラーの繰返し。（知らんけど）

トライアンドエラーは、和製英語で、試行錯誤という意味らしい。

英語だと、

> Trial and error

***脱線を戻そう***

さっきの出力した結果には、改行が入ってなかったんだ。

なので、改行を入れてみる。

# １〜１００までの数字を出力(改行コードを入れてみる)

改行とは。改めて行。人生とは行の連続だ。（多分業のことを言っている）

なんて意味のわからないことを言うのはもう辞めよう。多分無理だけど。

改行コードって[CR]とか[LF]とか[CRLF]とかですね。

リテラル文字に表してみると、"\r" "\n"ですね。

リテラル文字って・・・なんのこっちゃ分からない。

気になる人は<a href="https://ja.wikipedia.org/wiki/%E6%94%B9%E8%A1%8C%E3%82%B3%E3%83%BC%E3%83%89"> 改行コード (wikipedia)</a>をみてください。



***脱線を戻そう***

```php
<?php
for($i=1;$i<=100;$i++){
    echo $i."\n"; // ←文字列結合で数字と改行文字を合体！
}
```

すると、1〜100を改行付きで出力しましたとさ。
めでたしめでたし。

```
1
2
3
4
....省略...
```


ちなみにMacの日本語キーボードだと。

[option]キー + [¥]キーで、[\n]になるよ。

# 変数のパース

```php
echo $i."\n";
```

は、

```php
echo "{$i}\n";
```

でも良いし、

```php
echo "${i}\n";
```

でも良いんだ。こんな書き方を**変数のパース**って呼ぶそう。

書き方は自由。つまり言論の自由。

でも、シングルクォテーションで囲った文字は、変数のパースしてくれないから気をつけよう。

***脱線を戻そう***

# Fizzを出力してみよう。

で、次に、Fizzを出力してみる。

出力する数字を3で割ってみて、余りが0なら、３の倍数ってこと。

PHP的には```$i % 3```で求めます。

今回 % は 代数演算子 です。

```
$a % $b → (%は剰余) → つまり $a を $b で割った余り
```

PHPで表すと以下のようになります。

```php
if( $i % 3  == 0 ){
     // $iを3で割った余りが、0の場合(つまり、3で割り切れた時) ここを通ります。
}
```

# 改めて、条件分岐について復習。

条件分岐には **if** と **else** があります。

**if**はもしも**True** の場合、 **else**は**False**の場合に動作します。

```php
if( $foo ) {
     //$fooがTrueの場合ここを通ります。
} else {
    //$fooがFalseの場合ここを通ります。
}
```

※$fooは例えばの変数です。

### TrueかFalseは比較演算子の結果

```php
($i % 3  == 0)
// ↑の計算式の通りなら、True。　
// ↑の計算式の通りにならない場合は、False。
```



この流れを当てはめてみると。

```php
<?php
for($i=1;$i<=100;$i++){
    if($i % 3 == 0 ){
        // $iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } else {
        // $iを3で割った余りが、0以外の場合(つまり、3で割り切れない場合)
        echo $i."\n";
    }
}
```

と。なりました。

このプログラムの出力結果は、以下のようになりました。

```
1
2
Fizz
4
5
Fizz
7
8
...省略...
```
それっぽいのができた。

目出度目出度。

これメデタシメデタシって読むんだね。

# Buzzを出力。

**elseif**を使う時が出てきました。

Buzzは5で割り切れる場合に出力します。

phpのマニュアルより、elseifをみてみる。

```php
<?php
if ($a > $b) {
    echo "aはbより大きい";
} elseif ($a == $b) {
    echo "aはbと等しい";
} else {
    echo "aはbより小さい";
}
```

これをBuzzに当てはめてみましょう。

まずはシンプルに。elseif を追加してみます。

```php
<?php
for($i=1;$i<=100;$i++){
    if($i % 3 == 0 ){
        //$iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } elseif($i % 5 == 0){
        //$iを5で割った余りが、0の場合(つまり、5で割り切れた時)
        echo "Buzz\n";
    } else {
        echo $i."\n";
    }
}
```

結果は。

```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
Fizz
...省略...
```

となりました。

15　の場合に、FizzBuzzと出力したいですが、このままだとFizzの出力となります。

この問題を解消するため、単純に、elseif を加えてみます。

```php
<?php
for($i=1;$i<=100;$i++){
    if( $i % 3 == 0 ){
        //$iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } elseif ( $i % 5 == 0 ){
        //$iを5で割った余りが、0の場合(つまり、5で割り切れた時)
        echo "Buzz\n";
    } elseif ( $i % 3 == 0 && $i % 5 == 0 ){
        //$iを3で割った余りが、0かつ、
        //$iを5で割った余りが、0の場合
        echo "FizzBuzz\n";
    } else {
        echo $i."\n";
    }
}
```

# あy .... 過ち。

このプログラムには間違いがあります。 15の時、Fizzしか出力されません。


> 3の余りが0かつ、5の余りが0の場合、

は、

> 必ず、3の余りが0の条件にマッチする

なので。

3の倍数の場合で5の倍数の場合、一番上の ```echo "Fizz\n";```　の部分が動いてしまうの。


**FizzBuzz**を出力したければ、3の余りが0の条件分岐より、先に、

3の余りが0かつ、5の余りが0　かどうかを判定する必要があります。

結果このようなプログラムに修正されました。

```php

<?php
for($i=1;$i<=100;$i++){
    if ( $i % 3 == 0 && $i % 5 == 0 ){
        //$iを3で割った余りが、0かつ、
        //$iを5で割った余りが、0の場合
        echo "FizzBuzz\n";
    } elseif ( $i % 5 == 0 ){
        //$iを5で割った余りが、0の場合(つまり、5で割り切れた時)
        echo "Buzz\n";
    } elseif( $i % 3 == 0 ){
        //$iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } else {
        echo $i."\n";
    }
}
```

結果、うまくいきました。

```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
...省略...
```

# 改善案

少し改善する方法を考えてみます。

```php
if ( $i % 3 == 0 && $i % 5 == 0 ){
```

この部分は、もしかすると、

```php
if ( $i % 15 == 0 ){
```

に置き換えれるかもしれないな。とか。

その考えを当てはめてみました。

```php

<?php
for($i=1;$i<=100;$i++){
    if ( $i % 15 == 0 ){
        //$iを3で割った余りが、0かつ、
        //$iを5で割った余りが、0の場合
        echo "FizzBuzz\n";
    } elseif ( $i % 5 == 0 ){
        //$iを5で割った余りが、0の場合(つまり、5で割り切れた時)
        echo "Buzz\n";
    } elseif( $i % 3 == 0 ){
        //$iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } else {
        echo $i."\n";
    }
}
```

# 関数を使ってみよう。 (オマケ)

FizzBuzzの出力を関数にしてみよう。

関数って、↓↓↓こんなやつ。

```php
function FizzBuzzEcho($num){
    echo "${num}\n";
}
```


関数のイメージはこんな感じでやってみる。

関数は、引数が合って、戻り値が合って、って色々ありそうだけど、大事なことは 処理を１つにまとめた部品にしてしまうこと。

今回作る関数は、FizzBuzzEcho関数。

やることは、


> * 渡した数字が15の倍数の場合はFizzBuzzを出力、 
> * 渡した数字が3の倍数の場合はFizzを出力、 
> * 渡した数字が5の倍数の場合はBuzzを出力、 
> * それ以外は、渡した数字を出力する関数。


関数の使い方は簡単。

```php

FizzBuzzEcho(1);
FizzBuzzEcho(3);
FizzBuzzEcho(5);
FizzBuzzEcho(15);
```

こんな感じで使えます。

結果は、

```
1
3
5
15
```

関数を正しい結果になるよう修正してみよう。

```php

<?php

function FizzBuzzEcho($num){
    if ( $num % 15 == 0 ){
        //$iを3で割った余りが、0かつ、
        //$iを5で割った余りが、0の場合
        echo "FizzBuzz\n";
    } elseif ( $num % 5 == 0 ){
        //$iを5で割った余りが、0の場合(つまり、5で割り切れた時)
        echo "Buzz\n";
    } elseif( $num % 3 == 0 ){
        //$iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } else {
        echo $num."\n";
    }
}

FizzBuzzEcho(1);
FizzBuzzEcho(3);
FizzBuzzEcho(5);
FizzBuzzEcho(15);
```

結果は。

```
1
Fizz
Buzz
FizzBuzz
```

が出力された。問題ないですね。

# 繰り返しの中で、関数を呼び出してみよう。

こんな感じで呼び出す。

```php
<?php 
for($i=1;$i<=100;$i++){
    FizzBuzzEcho($i);
}
```
でできたプログラムは↓こんな感じ。

```php
<?php
function FizzBuzzEcho($num){
    if ( $num % 15 == 0 ){
        //$iを3で割った余りが、0かつ、
        //$iを5で割った余りが、0の場合
        echo "FizzBuzz\n";
    } elseif ( $num % 5 == 0 ){
        //$iを5で割った余りが、0の場合(つまり、5で割り切れた時)
        echo "Buzz\n";
    } elseif( $num % 3 == 0 ){
        //$iを3で割った余りが、0の場合(つまり、3で割り切れた時)
        echo "Fizz\n";
    } else {
        echo "${num}\n";
    }
}

for($i=1;$i<=100;$i++){
    FizzBuzzEcho($i);
}
```

動かした結果は、↓となった。

```
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
...省略...
```

こんな感じ。です。

関数の大事なことは、役割を明確にすること。

名前を丁寧につけること。

名前を丁寧につけて、役割を明確にすると、

やりたいことが伝わりやすくなります。

```php
for($i=1;$i<=100;$i++){
    FizzBuzzEcho($i);
}
```

そして、役割を明確にして、名前を丁寧につけることは、**構造化プログラミング**の一歩。

参考：　<a href="https://ja.wikipedia.org/wiki/%E6%A7%8B%E9%80%A0%E5%8C%96%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0">構造化プログラミング (wikipedia)</a>


# 以上。