Blogの生存報告がてら。
ちょっと旬の過ぎた話題ですが、逆FizzBuzz問題をC++で、自分なりにがんばってオブジェクト指向っぽく解いてみます。
逆FizzBuzz問題
FizzBuzzゲームは英語圏での定番飲み会用ゲームで、日本で言うナベアツゲームみたいなものです。
ルールは各人が1から順に数を言っていき、3の倍数のときには数字の代わりにFizz、5の倍数のときにはBuzz、3かつ5の倍数のときにはFizzBuzzを言うというものです。
具体的にはこうなります: 1, 2, Fizz, 4, Buzz, Fizz, 7, 8, Fizz, Buzz, …
プログラミング界隈では初歩的なコーディング問題として、相手が本当にプログラミングができるのかどうかを知る問題として使われるそうです。(現場で本当に使われているのかは知りません。)
さて、逆FizzBuzz問題というのは、これに関連した問題の逆問題として定義されます。
まず、1からでなく適当な数字から始め、さらに数字を言わないFizzBuzz問題を考えます。
例えば25から始めるとすると、25はBuzz、26は飛ばす、27はFizz、28は飛ばす、29は飛ばす、30はFizzBuzz、… となり、この結果はBuzz, Fizz, FizzBuzz, … となります。
これの逆問題を考えます。つまり、FizzやBuzzやFizzBuzzの羅列でできた文字列が与えられたとき、結果がそれに一致するような数列を求めたい、それを逆FizzBuzz問題と定義します。
それだけだと答えが複数あるので、今回はその中で最小の数列の最も小さい数から始まるものを答えとしましょう。
具体的な問題例とその答えは以下のようになります。
- “Fizz”なら3
- “Fizz, Buzz”なら9,10 (3,4,5より短い)
- “FizzBuzz”なら15
- “FizzBuzz, Fizz”なら15, 16, 17, 18
より詳しくは元ネタを和訳されている以下のリンクを参照してください:
逆FizzBuzz問題 (Inverse FizzBuzz) – 猫とC#について書くmatarilloの雑記
オブジェクト指向で逆FizzBuzz問題
ここからプログラミングの話題。
先に挙げたリンク先(とさらにその先の英語原文)では、オブジェクト指向プログラミングがプログラマーに滅びをもたらす思想であると認定され、代わりに関数型プログラミングが広く認められた近未来で逆FizzBuzz問題を解くお話になっています。
まあ、オブジェクト指向が悪であるかどうかは議論を避けるとして、ここでは2016年になってもやっぱりオブジェクト指向は世の中を支配していた、そしてその世界で逆FizzBuzz問題もオブジェクト指向のノリで解く必要に迫られたらどうなるのかをやってみた、という内容になります。(そもそも私は関数型プログラミングをきちんと勉強していない人なので、善悪の議論ができません。)
言語は例によってC++11です。だいたい次のように決めておきます。
- 出力は逆FizzBuzz問題の解の数列の範囲。例:”Fizz Buzz” → “[3,5]”
- 入力が空文字のときは[0,0]を返す。
- 解がないときは適当に文句を返す。
先にソースコードを書いてしまいましょう。
続きを読む