gracetory’s blog

東池袋にある合同会社グレストリのエンジニアブログです

春だからPHPでFizzBuzz問題やってみよう

f:id:ykira:20190308122139j:plain

こんにちは、こんばんは、おはようございます。

花粉がきつくなってきたykiraです。もう春ですね。

暖かくなって来たので、そろそろ本気出す予定の方も多いのではないでしょうか。

f:id:ykira:20190308101546p:plain

今回は就職試験などでも出される? FizzBuzz問題をPHPで解いてみようと思います。

FizzBuzz問題 is 何?

wikipediaによると、下記のような条件で1〜100までを画面出力をする問題のことです。

3で割り切れる場合は「Fizz」、5で割り切れる場合は「Buzz」、両者で割り切れる場合(すなわち15で割り切れる場合)は「FizzBuzz」

読み方は「フィズ・バズ」です。

Jeff Atwoodという人がFizzBuzz問題として提唱したらしいです。

FizzBuzzに入る文字は、3で割り切れる場合は「宮守」、5で割り切れる場合は「あおい」、3でも5でも割り切れる場合は「万策尽きたー」とかなんでもOKです。

普通の解き方

素直に書くと下記のような感じでしょうか。書き方はいろいろあるので好きな書き方でOKです。

for ($i = 1; $i <= 100; $i++) {
    $output = $i;
    if ($i % 3 == 0) {
        $output = "宮守";
    }
    if ($i % 5 == 0) {
        $output = "あおい";
    }
    if ($i % 15 == 0) {
        $output = "万策尽きたー";
    }
    echo $output.",";
}

出力はコチラ。出来てますね。

1,2,宮森,4,あおい,宮森,7,8,宮森,あおい,11,宮森,13,14,万策尽きたー,16,17,宮森,19,あおい,宮森,22,23,宮森,あおい,26,宮森,28,29,万策尽きたー,31,32,宮森,34,あおい,宮森,37,38,宮森,あおい,41,宮森,43,44,万策尽きたー,46,47,宮森,49,あおい,宮森,52,53,宮森,あおい,56,宮森,58,59,万策尽きたー,61,62,宮森,64,あおい,宮森,67,68,宮森,あおい,71,宮森,73,74,万策尽きたー,76,77,宮森,79,あおい,宮森,82,83,宮森,あおい,86,宮森,88,89,万策尽きたー,91,92,宮森,94,あおい,宮森,97,98,宮森,あおい,

プログラムが書けるかどうかを見る問題なので、プログラマからするとこれ解けて当たり前ですね。

割り算とか余りとか使わない解き方

プログラマの試験の場合に、こんな感じで○○を使わないで解いてくださいみたいな条件が付く場合が多いです。

ちょっと長くなりましたがこんなの考えました。

const NUM3 = 3;
const NUM5 = 5;
const NUM15 = 15;

$num3 = NUM3;
$num5 = NUM5;
$num15 = NUM15;
for ($i = 1; $i <= 100; $i++) {
    $output = $i;
    if ($i == $num3) {
        $output = "宮森";
        $num3 += NUM3;
    }
    if ($i == $num5) {
        $output = "あおい";
        $num5 += NUM5;
    }
    if ($i == $num15) {
        $output = "万策尽きたー";
        $num15 += NUM15;
    }
    echo $output.",";
}

現在の数字が対象だったら$outputに文字列入れて、次の判定用の数字に変数を更新するイメージです。

ちょっと考えましたねー、おもしろい。

ifとswitchを使わない解き方

ぱっと思いつくのが三項演算です。カッコつけたので少しはわかりやすいかな?

for ($i = 1; $i <= 100; $i++) {
    echo $i % 15 ? ($i % 3 ? ($i % 5 ? $i : "あおい") : "宮森") : "万策尽きたー";
    echo ",";
}

三項演算は入れ子にできるのでこんな感じになりますね。

if使うよりも簡単に書けていいですね。

他にもarray_fill_keysとか使って配列でやる方法とかもあるみたいです。

↓のQiitaがまとめられていて面白かったです。

qiita.com

最短のコードは何しているかぱっと見よくわかりませんね^^;;;

他の解き方

echo "1,2,宮森,4,あおい,宮森,7,8,宮森,あおい,11,宮森,13,14,万策尽きたー,16,17,宮森,19,あおい,宮森,22,23,宮森,あおい,26,宮森,28,29,万策尽きたー,31,32,宮森,34,あおい,宮森,37,38,宮森,あおい,41,宮森,43,44,万策尽きたー,46,47,宮森,49,あおい,宮森,52,53,宮森,あおい,56,宮森,58,59,万策尽きたー,61,62,宮森,64,あおい,宮森,67,68,宮森,あおい,71,宮森,73,74,万策尽きたー,76,77,宮森,79,あおい,宮森,82,83,宮森,あおい,86,宮森,88,89,万策尽きたー,91,92,宮森,94,あおい,宮森,97,98,宮森,あおい";

とりあえずechoさえ分かっていれば書けそうです。

これ出力的には問題ないですが、プログラムが出来るかどうかの試験だとNGなのかもしれませんね。

$output = array(1,2,"宮森",4,"あおい","宮森",7,8,"宮森","あおい",11,"宮森",13,14,"万策尽きたー",16,17,"宮森",19,"あおい","宮森",22,23,"宮森","あおい",26,"宮森",28,29,"万策尽きたー",31,32,"宮森",34,"あおい","宮森",37,38,"宮森","あおい",41,"宮森",43,44,"万策尽きたー",46,47,"宮森",49,"あおい","宮森",52,53,"宮森","あおい",56,"宮森",58,59,"万策尽きたー",61,62,"宮森",64,"あおい","宮森",67,68,"宮森","あおい",71,"宮森",73,74,"万策尽きたー",76,77,"宮森",79,"あおい","宮森",82,83,"宮森","あおい",86,"宮森",88,89,"万策尽きたー",91,92,"宮森",94,"あおい","宮森",97,98,"宮森","あおい");

foreach ($output as $value) {
    echo $value.",";
}

配列とループは分かってるよ!的な書き方。

ifとかswitch使わないという条件ならありかもしれませんね?

まとめ

使い古された感があるFizzBuzz問題ですが、いろいろな解き方があるというのを今回改めて調べて知りました。

解き方に条件をつけると普段の業務では使わないような言語の深い知識が必要になってきます。

そういう知識がピンチの時に役に立ちそうですね。

面白かったのでまた他の題材見つけたら挑戦してみようと思います!

ここまで読んでいただきありがとうございました!!