MENU

FizzBuzzはif文なしで書ける?Pythonicコードの遊び方と驚きの解法

プログラミングの学習を始めたばかりの人も、ベテランのエンジニアも、一度は「FizzBuzz問題」に挑戦したことがあるでしょう。3の倍数で”Fizz”、5の倍数で”Buzz”、両方の倍数で”FizzBuzz”、それ以外は数字を出力する。シンプルながらも、条件分岐の基本を学ぶには最適な問題です。

しかし、いつもifelifelseの羅列で「なんだか味気ないな…」「もっとスマートな書き方はないのかな?」と感じていませんか? 私もそうでした。FizzBuzzの問題が出されるたびに、当たり前のように条件分岐を書き並べていました。「これでいいんだ、これが普通なんだ」と自分に言い聞かせながらも、心のどこかでは「もっと洗練された方法があるんじゃないか?」という漠然とした停滞感を抱えていたんです。まるで、いつも同じ道を通って目的地に向かうことに疑問を持たない旅人のように。

ある日、Pythonのコミュニティで「if文を使わないFizzBuzz」という挑戦を見かけました。正直なところ、最初は「そんなの無理だろう」「わざわざifを避ける意味があるのか?」と斜に構えていました。しかし、実際にそのコードを見たとき、私のプログラミングに対する固定観念はガラガラと音を立てて崩れ去ったのです。それはまるで、目の前で魔法が披露されたかのような衝撃でした。

「え、こんな書き方ができるの…?」「こんなに短いコードで、あの複雑な条件分岐を表現できるなんて!」

衝撃と同時に、長年の呪縛から解放されたような覚醒感がありました。if文という“絶対的な存在”が、実は選択肢の一つに過ぎなかったと知った瞬間です。まるで、いつも使っていた包丁の他に、ピーラーやスライサーといった、もっと効率的で美しい調理器具があったことに気づいた料理人のようでした。

では、一体どのようにしてif文の呪縛から逃れるのでしょうか? ここでは、Pythonの持つ強力な機能と柔軟な発想を組み合わせた、いくつかの「Pythonicな」解法をご紹介します。

1. 辞書(Dictionary)を使ったマッピング

最も直感的で、可読性も損ないにくいアプローチの一つが、辞書を使ったマッピングです。割り切れる数と出力文字列を対応させ、合成していく方法です。

“`python

results = {

(True, True): “FizzBuzz”,

(True, False): “Fizz”,

(False, True): “Buzz”,

(False, False): “”

}

for i in range(1, 101):

is_fizz = (i % 3 == 0)

is_buzz = (i % 5 == 0)

output = results[(is_fizz, is_buzz)] or str(i)

print(output)

“`

これはif文の条件分岐を、辞書のキーとして表現しています。論理値の組み合わせがそのまま結果にマッピングされるため、非常に分かりやすいですね。

2. ブール値と文字列結合のトリック

Pythonでは、ブール値(True/False)を数値として扱うことができます(Trueは1、Falseは0)。この特性と文字列の結合を巧みに利用する方法です。

“`python

for i in range(1, 101):

fizz = “Fizz” * (i % 3 == 0)

buzz = “Buzz” * (i % 5 == 0)

print(fizz + buzz or str(i))

“`

"Fizz" (i % 3 == 0) の部分がミソです。i % 3 == 0Trueなら"Fizz" 1で”Fizz”、Falseなら"Fizz" * 0で空文字列""になります。このテクニックは、Pythonの真理値判定の柔軟性を最大限に活かした、まさにPythonicな発想です。

3. リストと`join()`を使った洗練された方法

さらに一歩進んだ方法として、リストとstr.join()を組み合わせる方法もあります。

“`python

より厳密にif文の羅列を避けるアプローチの例

mapping = {3: “Fizz”, 5: “Buzz”}

for i in range(1, 101):

result = “”.join(mapping[key] for key in mapping if i % key == 0)

print(result or str(i))

“`

このコードは、if文の羅列を避け、より宣言的なスタイルでFizzBuzz問題を解決しています。resultを生成する部分でifが使われていますが、これはリスト内包表記の一部であり、従来のif/elif/elseの構造とは異なるアプローチです。

なぜ`if`文を避けることが「Pythonic」なのか?

if文を避けることは、単なる「コードゴルフ」や「トリッキーなコード」を書くことではありません。Pythonの言語機能の奥深さを知り、問題解決に対する柔軟な思考を養う絶好の機会です。

  • 簡潔性: コードが短くなり、条件分岐の複雑さが視覚的に軽減されます。
  • 表現力: Pythonが提供するデータ構造(辞書、リスト)や演算子の特性を最大限に活かすことで、より「Pythonらしい」表現が可能になります。
  • 思考の拡張: 既成概念にとらわれず、「もっと良い方法はないか?」と探求する姿勢は、他のより複雑な問題解決にも応用できる貴重なスキルです。

コードが短くなり、見通しが良くなるだけでなく、何よりも「こんな書き方もできるんだ!」というプログラミングの楽しさ、創造的な喜びを再発見できるはずです。まるで、いつも同じ材料で料理していたのに、新しいスパイスや調理法を見つけて、料理の幅が格段に広がったような感覚です。

まとめ

あなたのFizzBuzz、まだifに頼っていますか? 一歩踏み出して、Pythonicなコードの遊び方を探求してみませんか? 最初は戸惑うかもしれませんが、この挑戦を通じて、きっと新しい発見と、より洗練されたコードを書く自信が手に入るはずです。

FizzBuzzは、プログラミングの奥深さと楽しさを教えてくれる、最高のパズルなのです。さあ、あなたもif文の壁を乗り越え、Pythonicな表現の自由を体験してください。