グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



FizzBuzz問題をPHPで解いてみよう

今回は最もメジャーな基本的なプログラミング問題である「FizzBuzz問題」について紹介していきます。

プログラマの採用などでプログラミング能力を確認する際によく登場する問題です。

「FizzBuzz」問題とは?

そもそもFizz Buzzとは、英語圏で行われている言葉遊びの一種です。

プレイヤーは円状に座る。最初のプレイヤーは「1」と数字を発言する。次のプレイヤーは直前のプレイヤーの次の数字を発言していく。ただし、3の倍数では「Fizz」(Bizz Buzzの場合は「Bizz」)、5の倍数では「Buzz」、両者の公倍数(すなわち15の倍数)では「Fizz Buzz」(Bizz Buzzの場合は「Bizz Buzz」)を数の代わりに発言しなければならない。発言を間違えた者や、ためらった者は脱落となる。引用先: wikipedia

このゲームをプログラミングに応用したものが「Fizz Buzz問題」です。

  • 1から100までの数をプリントするプログラム
  • 3の倍数の時には数の代わりに「Fizz」とプリントする
  • 5の倍数の時には数の代わりに「Buzz」とプリントする
  • 3と5両方の倍数の時には数の代わりに「FizzBuzz」とプリントする
プログラマーの基本的な素養をみるための、ごく簡単な問題。 引用先: はてなキーワード
このゲームをコンピュータ画面に表示させるプログラムとして作成させることで、コードを作れないプログラマ志願者を見分ける手法をジェフ・アトウッドが「FizzBuzz 問題」として提唱した。その提唱はインターネットの様々な場所で議論の対象になっている。引用先: wikipedia

一次ソース:https://blog.codinghorror.com/why-cant-programmers-program/

この記事を執筆時に動作検証を行った筆者の環境

PHP 7.0.14 (cli)

実際にPHPで解いてみよう 【初級編】

まずは愚直に、先述した問題例の順番に沿って実装してみましょう。

【1】1から100までの数をプリントする

<?php
declare(strict_types=1);

for ($i = 1; $i <= 100; $i++) {
    echo $i;
    echo PHP_EOL;
}

【2】3の倍数の時には数の代わりに「Fizz」とプリントする

<?php
declare(strict_types=1);

for ($i = 1; $i <= 100; $i++) {
    if ($i % 3 === 0) {
        echo 'Fizz';
    } else {
        echo $i;
    }

    echo PHP_EOL;
}

【3】5の倍数の時には数の代わりに「Buzz」とプリントする

<?php
declare(strict_types=1);

for ($i = 1; $i <= 100; $i++) {
    if ($i % 3 === 0) {
        echo 'Fizz';
    } elseif ($i % 5 === 0) {
        echo 'Buzz';
    } else {
        echo $i;
    }

    echo PHP_EOL;
}

【4】3と5両方の倍数の時には数の代わりに「FizzBuzz」とプリントする

<?php
declare(strict_types=1);

for ($i = 1; $i <= 100; $i++) {
    if (($i % 3 === 0) && ($i % 5 === 0)) {
        echo 'FizzBuzz';
    } elseif ($i % 3 === 0) {
        echo 'Fizz';
    } elseif ($i % 5 === 0) {
        echo 'Buzz';
    } else {
        echo $i;
    }

    echo PHP_EOL;
}
 【4】3と5両方の倍数の時には数の代わりに「FizzBuzz」とプリントする
つまりは15の倍数ですね。
「FizzBuzz」とプリントするロジックを短縮できそうです。


<?php
declare(strict_types=1);

for ($i = 1; $i <= 100; $i++) {
    if ($i % 15 === 0) {
        echo 'FizzBuzz';
    } elseif ($i % 3 === 0) {
        echo 'Fizz';
    } elseif ($i % 5 === 0) {
        echo 'Buzz';
    } else {
        echo $i;
    }

    echo PHP_EOL;
}

上手にできました。

実行結果(外部サイトに移動します)
http://sandbox.onlinephpfunctions.com/code/ce36167657f89d96b0fbd76379925dd3512955c9

※「Execute code」ボタンを押すと実行結果が表示されます。

実際にPHPで解いてみよう 【応用編】

【5】「FizzBuzz」のロジックを関数化してみる

<?php
declare(strict_types=1);

function fizzBuzz(int $i): string
{
    $result = '';

    if ($i % 3 === 0) {
        $result .= 'Fizz';
    }

    if ($i % 5 === 0) {
        $result .= 'Buzz';
    }

    if (($i % 3 !== 0) && ($i % 5 !== 0)) {
        $result .= (string)$i;
    }

    return $result;
}

for ($i = 1; $i <= 100; $i++) {
    echo fizzBuzz($i), PHP_EOL;
}

実際にPHPで解いてみよう 【番外編】

【6】関数型言語風味に呼び出してみる ~array_function を添えて~

<?php
declare(strict_types=1);

function fizzBuzz(int $i): string
{
    $result = '';

    if ($i % 3 === 0) {
        $result .= 'Fizz';
    }

    if ($i % 5 === 0) {
        $result .= 'Buzz';
    }

    if (($i % 3 !== 0) && ($i % 5 !== 0)) {
        $result .= (string)$i;
    }

    return $result;
}

echo implode(
    PHP_EOL,
    array_map(
        'fizzBuzz',
        range(1, 100)
    )
);

【7】さらに関数型言語風に ~FizzBuzzの配列を作ればいいじゃない~

<?php
declare(strict_types=1);

$fizzBuzzFilter = function(int $num): callable {
    return function($i) use ($num) {
        return !($i % $num);
    };
};

$numbers = array_combine(range(1, 100), range(1,100));

$fizzArray = array_fill_keys(
    array_filter(
        $numbers,
        $fizzBuzzFilter(3)
    ),
    'Fizz'
);

$buzzArray = array_fill_keys(
    array_filter(
        $numbers,
        $fizzBuzzFilter(5)
    ),
    'Buzz'
);

$fizzBuzzArray = array_fill_keys(
    array_filter(
        $numbers,
        $fizzBuzzFilter(15)
    ),
    'FizzBuzz'
);

echo implode(
    PHP_EOL,
    array_replace(
        $numbers,
        $fizzArray,
        $buzzArray,
        $fizzBuzzArray
    )
), PHP_EOL;<

【8】さらに関数型言語風に Part2

<?php
declare(strict_types=1);

$fizzBuzzFilter = function(int $num): callable {
    return function($i) use ($num) {
        return !($i % $num);
    };
};

$fizzBuzzArrayGenerator = function(array $range, callable $filter, $word): array {
    return array_fill_keys(
        array_filter(
            $range,
            $filter
        ),
        $word
    );
};

$numbers = array_combine(range(1, 100), range(1,100));

echo implode(
    PHP_EOL,
    array_replace(
        $numbers,
        $fizzBuzzArrayGenerator($numbers, $fizzBuzzFilter(3), 'Fizz'),
        $fizzBuzzArrayGenerator($numbers, $fizzBuzzFilter(5), 'Buzz'),
        $fizzBuzzArrayGenerator($numbers, $fizzBuzzFilter(15), 'FizzBuzz')
    )
), PHP_EOL;

var_dump(memory_get_peak_usage() / 1024 / 1024);

【9】表示する文字を変更する事もできます。

<?php
declare(strict_types=1);

$fizzBuzzFilter = function(int $num): callable {
    return function($i) use ($num) {
        return !($i % $num);
    };
};

$fizzBuzzArrayGenerator = function(array $range, callable $filter, $word): array {
    return array_fill_keys(
        array_filter(
            $range,
            $filter
        ),
        $word
    );
};

$numbers = array_combine(range(1, 100), range(1,100));

echo implode(
    PHP_EOL,
    array_replace(
        $numbers,
        $fizzBuzzArrayGenerator($numbers, $fizzBuzzFilter(3), '西郷'),
        $fizzBuzzArrayGenerator($numbers, $fizzBuzzFilter(5), 'どん'),
        $fizzBuzzArrayGenerator($numbers, $fizzBuzzFilter(15), '西郷どん')
    )
), PHP_EOL;

さいごに

いかがでしたでしょうか。
今回の実装が正解という訳ではなく、様々なアプローチで解く方法が複数あります。
「FizzBuzz」問題の実装を通して、プログラミングの楽しさの一旦を、少しでも伝えられることが出来たら嬉しく思います。

アーティスではこのように様々なアプローチを模索し、実装していく素敵なプログラマを募集中です。

プログラマ募集情報はこちら

この記事を書いた人

アーティス
アーティス
創造性を最大限に発揮するとともに、インターネットに代表されるITを活用し、みんなの生活が便利で、豊かで、楽しいものになるようなサービスやコンテンツを考え、創り出し提供しています。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします