なぜ今更FizzBuzz?
僕みたいなゴリゴリの文系卒の駆け出しエンジニアにとってサーバースクリプトに触れてからぶち当たる最初の難関がFizzBuzz問題ではないでしょうか。
ようやく理解できるレベルまで到達したので、文系の皆さんにもわかりやすいようにまとめてみたいと思います。
そもそもFizzBuzzとは
そもそもコードを書く前に誰もが思うはず。
FizzBuzzってなんだ!!と。
FizzBuzzとは、過去に流行った「世界のナ○アツ」的なやつみたいです。
プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3の倍数では「Fizz」(Bizz Buzzの場合は「Bizz」)、5の倍数では「Buzz」、両者の公倍数(すなわち15の倍数)では「Fizz Buzz」(Bizz Buzzの場合は「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者や、ためらった者は脱落となる。
引用元:Fizz Buzz
つまり、1から自然数をカウントしていき、3の倍数と5の倍数、その両方の公倍数のとき(15の倍数)に任意の文字をechoさせてあげればよろしい。
それ以外のときは単に数字をechoさせるロジックで実装すればよろしい。
実践
<?php
for ($i = 1; $i <= 100; $i++) {
if ($i % 15 === 0) {
echo 'FizzBuzz' . "\n";
continue;
} elseif ($i % 3 === 0) {
echo 'fizz' . "\n";
continue;
} elseif ($i % 5 === 0) {
echo 'buzz' . "\n";
continue;
}
echo $i . "\n";
}
ざっくりこんな感じ。
(あくまで一例です。他にもっと簡単な記述あるよ!などあればご教授いただけると幸いです)
初見はちんぷんかんぷんと思うので、要点を順番に解説していきます。
①数字をひたすらカウントさせるコードを書く
for ($i = 1; $i <= 100; $i++) { //変数iが100になるまでechoを実行する
echo $i . "\n"; //数字が呼び出される(\nは見やすいように改行処理)
}
$i = 1
とは初期値1と定義。
$i++
とは$i = $i+1
の省略形でforが一回発動する毎に変数iに1を足してあげることです。
つまり、ここでは100になるまで変数$iを順にechoする。というコードが書かれています。
②3の倍数と5の倍数の時に処理を分岐させる
for ($i = 1; $i <= 100; $i++) { //変数iが100になるまで以下の処理をループ
if ($i % 15 === 0) { //15の倍数のとき
echo 'FizzBuzz' . "\n";
} elseif ($i % 3 === 0) { //3の倍数のとき
echo 'fizz' . "\n";
} elseif ($i % 5 === 0) { //5の倍数のとき
echo 'buzz' . "\n";
echo $i . "\n"; //条件以外の数字が呼び出される
}
3の倍数の処理から書きがちですが、プログラミングは上から処理が実行されるのでFizzBuzzの処理(15の倍数)は一番最初の条件として記述しましょう。
イメージとしては、
15の倍数のときにFizzBuzz出力→3の倍数のときにfizz出力→5の倍数のときにbuzz出力→
それ以外はカウントしたときの数字を出力。
条件内の
$i % 15 === 0
は変数$iを15で割った数が0ということ。
つまり$i % ○ === 0
とするころで、○の倍数が取れるということです。
===
は厳密に同じという意味。
条件式のイコールは曖昧な一致の==
だとエラーのリスクが上がるので基本===
で書きましょう。
③分岐に入ったらループ処理に戻してあげる
for ($i = 1; $i <= 100; $i++) { //変数iが100になるまで以下の処理をループ
if ($i % 15 === 0) { //15の倍数のとき
echo 'FizzBuzz' . "\n";
continue; //ここでループ処理に復帰させる
} elseif ($i % 3 === 0) { //3の倍数のとき
echo 'fizz' . "\n";
continue; //ここでループ処理に復帰させる
} elseif ($i % 5 === 0) { //5の倍数のとき
echo 'buzz' . "\n";
continue; //ここでループ処理に復帰させる
echo $i . "\n"; //条件以外の数字が呼び出される
}
②までの記述だと条件処理が行われた後に自然数を呼び出す処理も行われてしまうので、
各条件処理の最後にcontinue
を使いループ処理をforに戻してあげましょう。
今回はcontinueでループ処理に戻す方法を試していますが、以下の方法もシンプルですね。
for ($i = 1; $i <= 100; $i++) { //変数iが100になるまで以下の処理をループ
if ($i % 15 === 0) { //15の倍数のとき
echo 'FizzBuzz' . "\n";
} elseif ($i % 3 === 0) { //3の倍数のとき
echo 'fizz' . "\n";
} elseif ($i % 5 === 0) { //5の倍数のとき
echo 'buzz' . "\n";
} else { //上記条件以外のとき
echo $i . "\n"; //数字が呼び出される
}
}
おわりに
プログラミングっぽい処理の代表格のFizzBuzzは基本中の基本と言われています。
ロジックで説明されるとよくわからないFizzBuzz問題ですがコードで見ると意外と大したことないかと思います。
他にも解き方はたくさんあるかと思いますがこのやり方が僕にとって一番わかりやすくシンプルだったので、駆け出しエンジニアの皆さんに役立てられるように共有させていただきます。