FizzBuzz問題(フィズバズ問題)とは?ルール・由来・Python実装をわかりやすく解説
FizzBuzz問題(フィズバズ問題)は、1から100までの数を順に出力し、3の倍数を「Fizz」、5の倍数を「Buzz」、3と5の両方の倍数(=15の倍数)を「FizzBuzz」に置き換えるという課題です。数分で書ける簡単な内容ながら、繰り返し・条件分岐・剰余演算というプログラミングの基礎が一度に問われるため、学習の入り口として、また採用選考の足切り問題として世界的に使われています。この記事ではルールと具体例、2007年に広まった由来、Pythonでの実装、そして採用試験で実際に評価されるポイントまでを整理します。
まとめ:この記事の要点
- ルール:1〜100で、3の倍数→Fizz、5の倍数→Buzz、15の倍数→FizzBuzz、それ以外は数値をそのまま出力する。
- 判定順序が肝:15の倍数(またはFizzとBuzzの両方成立)を先に判定しないと、15が「Fizz」で終わり誤答になる。
- 由来:子どもの数遊び「Fizz Buzz」が原型。2007年にImran Ghoryが採用選考に用いることを提唱し、Jeff Atwoodのブログ記事で一気に広まった。
- 採用試験での評価軸:正しく動くかだけでなく、判定順序・可読性・命名・重複排除など「基礎を丁寧に書けるか」を見られる。
- 凝った解法の注意:ワンライナーや文字列連結の技巧は面白いが、面接では動作の明快さと読みやすさが優先される。
FizzBuzz問題のルールと出力例
FizzBuzzの仕様は次の4条件だけです。上から順に判定するのが定石です。
- 3でも5でも割り切れる数(15の倍数)→ FizzBuzz
- 3で割り切れる数 → Fizz
- 5で割り切れる数 → Buzz
- どれにも当てはまらない数 → その数値をそのまま
1から15までを実際に出力すると次のようになります。15で初めて「FizzBuzz」が現れる点が、後述する判定順序の注意点につながります。
| 数 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 出力 | 1 | 2 | Fizz | 4 | Buzz | Fizz | 7 | 8 | Fizz | Buzz | 11 | Fizz | 13 | 14 | FizzBuzz |
「3の倍数か」を判定する道具が剰余演算子です。多くの言語で % と書き、i % 3 が0なら3で割り切れる、と判断します。FizzBuzzが基礎練習に向くのは、この剰余・比較・分岐・ループを1問で通しで使うからです。
FizzBuzzの由来と「プログラマを選別する」という背景
子どもの遊びから採用選考の定番への変遷
「Fizz Buzz」はもともと英語圏で遊ばれる数の言葉遊びで、順番に数を数えながら3の倍数で「Fizz」、5の倍数で「Buzz」と言い、割り算の学習に使われてきました。これをプログラミングの選考に持ち込んだのが、開発者のImran Ghory氏です。2007年1月24日の記事「Using FizzBuzz to Find Developers who Grok Coding」で、簡単すぎるくらいの課題を採用選考に用いることで「コードを書ける人」と「書けない人」をふるい分けられると論じました。
これを広く知らしめたのが、Jeff Atwood氏が2007年2月26日にブログ「Coding Horror」へ投稿した「Why Can’t Programmers.. Program?」です。情報系の学位を持つ応募者でも、FizzBuzz程度の課題をその場で書けない人が珍しくない、という指摘が大きな反響を呼び、FizzBuzzは面接課題の代名詞になりました。
簡単すぎる問題を採用試験で使う理由
目的は難問で優劣をつけることではなく、最低限の実装力を短時間で確認する足切りです。ループを回し、剰余で条件を分け、正しい順序で出力するという当たり前の手続きを、詰まらずに書けるか。ここでつまずく応募者を早い段階で見分けられるため、コストの低いスクリーニングとして機能します。だからこそ「解けること」自体は加点になりにくく、後述の書き方の質で差がつきます。
PythonでのFizzBuzz実装
Pythonでの最も素直な書き方は、for文でループし、if / elif で上から条件を判定するものです。15の倍数を最初に判定するのがポイントで、ここを外すと3の倍数の分岐が先に成立して15が「Fizz」になってしまいます。
for i in range(1, 101):
if i % 15 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
i % 15 == 0 の代わりに i % 3 == 0 and i % 5 == 0 と書いても同じ意味です。「15」というマジックナンバーを避け、条件の意図(3でも5でも割り切れる)を明示したいなら後者が読みやすくなります。判定順序さえ守れば、この素直な形が採用試験でもっとも安全な解答です。
エレガントな解法と「凝りすぎ」の落とし穴
FizzBuzzは短いだけに、技巧を競う題材にもなります。よく知られるのが、条件を満たしたときだけ文字列を連結し、空なら数値を出す書き方です。
for i in range(1, 101):
s = "Fizz" * (i % 3 == 0) + "Buzz" * (i % 5 == 0)
print(s or i)
Pythonでは真偽値が数値の1・0として扱えるため、"Fizz" * (i % 3 == 0) は条件が真なら「Fizz」、偽なら空文字になります。s or i は、sが空文字(偽)なら数値iを出す、というイディオムです。分岐を明示せずに15の倍数も自然に処理できる、無駄のない書き方です。
ただし面接や実務では、こうした技巧を最善解と考えないほうがよい場面が多いのが実情です。採用試験で見られているのは賢さより読みやすさと正確さで、初見の人がすぐ意味を追える素直なif文のほうが好まれます。ワンライナーや型変換に頼ったトリックは、レビューで意図を説明できて初めて価値になります。まず正しく動く明快な版を書き、余裕があれば「別解としてこう短くも書けます」と添えるのが、実力を伝える順番として堅実です。可読性そのものの評価軸はソースコード品質とは何かを整理した記事も参考になります。
他言語でのFizzBuzz(JavaScript・Java)
ロジックは言語が変わっても同じで、違うのは構文とループの書き方だけです。JavaScriptでは、Fizz・Buzzを個別に連結し、空なら数値を出す形が簡潔です。
for (let i = 1; i <= 100; i++) {
let s = "";
if (i % 3 === 0) s += "Fizz";
if (i % 5 === 0) s += "Buzz";
console.log(s || i);
}
Fizz・Buzzを別々のif文で足していくため、15の倍数では自然に「FizzBuzz」が組み上がり、15を特別扱いする分岐が不要になります。Javaでも考え方は同じで、文字列を組み立ててから空かどうかで出力を切り替えます。
for (int i = 1; i <= 100; i++) {
StringBuilder sb = new StringBuilder();
if (i % 3 == 0) sb.append("Fizz");
if (i % 5 == 0) sb.append("Buzz");
System.out.println(sb.length() == 0 ? i : sb);
}
言語ごとの制御構文やデータ構造をFizzBuzzで一巡させると、基礎の差分だけを効率よく確認できます。より体系的にアルゴリズムを学ぶ導入としてはJavaScriptで学ぶ基本的なアルゴリズムの解説記事も合わせて読むと理解が進みます。
よくある間違いと評価される観点
FizzBuzzで実際につまずく・減点される箇所は、ほぼ決まっています。
- 判定順序の誤り:3・5の分岐を先に書き、15の倍数の分岐を最後に置くと、15が「Fizz」で確定して「FizzBuzz」が出ない。上から「15→3→5」の順にするか、Fizz・Buzzを連結する方式にする。
- 範囲の取り違え:問題は1から100まで(100を含む)。
range(1, 101)のように終端を含める範囲指定にする。 - マジックナンバーの放置:3・5・15を直接埋め込むより、条件の意味が読み取れる書き方(
i % 3 == 0 and i % 5 == 0など)にすると保守しやすい。 - 重複した判定:同じ剰余計算を何度も書かず、必要なら変数に束ねる。短い問題でも重複排除の姿勢は見られている。
逆に評価されるのは、要件を正しく満たしたうえで、命名・分岐・出力が素直に読めることです。動作の正しさは前提で、そこから先の「丁寧さ」で差がつきます。
FizzBuzzの発展形と次のステップ
基本のFizzBuzzを書けたら、ルールを少し変えるだけで難度を上げられます。よくある発展問題は次のようなものです。
- 倍数の追加:7の倍数で「Whizz」を追加するなど、条件を増やす。分岐の順序と組み合わせ(21や35、105の倍数)の扱いが一気に難しくなる。
- 範囲や置換文字の可変化:3や5、上限100を引数で受け取れるよう関数化し、ハードコードを排除する。テストが書きやすい構造になる。
- 大きな範囲・性能:1〜数百万のように範囲を広げ、出力のまとめ方や計算量を意識する。
こうした変形は「要件が増えたときにコードを壊さず拡張できるか」を試す練習になります。さらに実戦的なアルゴリズム課題に進みたい場合は、AtCoderなどの競技プログラミングで段階的に難度を上げていくのが定番の流れです。
よくある質問(FAQ)
FizzBuzz問題(フィズバズ問題)とは何ですか?
1から100までの数を順に出力し、3の倍数を「Fizz」、5の倍数を「Buzz」、15の倍数を「FizzBuzz」に置き換えるプログラミングの基礎課題です。ループ・条件分岐・剰余演算をまとめて確認できるため、学習と採用選考の両方で広く使われています。
FizzBuzzの由来は何ですか?
英語圏の子ども向けの数の言葉遊び「Fizz Buzz」が原型です。プログラミングの選考課題としては、2007年1月にImran Ghory氏が提唱し、同年2月にJeff Atwood氏がブログ「Coding Horror」で取り上げたことで一気に定着しました。
なぜこんな簡単な問題が採用試験で使われるのですか?
難易度で優劣をつけるためではなく、最低限の実装力を短時間で確認する足切りのためです。ループと条件分岐を正しい順序で書けるかという基本を、詰まらずに実装できるかを見ています。
PythonでFizzBuzzを書くにはどうすればよいですか?
for文で1〜100を回し、if / elif で「15の倍数→3の倍数→5の倍数→それ以外」の順に判定して出力します。15の倍数を最初に判定するのが誤答を防ぐコツです。
15の倍数はなぜ「FizzBuzz」になるのですか?
15は3でも5でも割り切れるため、Fizzの条件とBuzzの条件を同時に満たすからです。そのため両方を連結した「FizzBuzz」を出力します。判定を分岐で書く場合は、この15の倍数を最初にチェックする必要があります。