わんくま祭り化してきた感のある「FizzBuzz 問題」ですが、事の発端に戻って。
高度なプログラミング(C# と VB.NET の質問掲示板)より:
自力で何かを作りたいと思いますが、住所録だとかスケジュール帳、お絵かきソフト、画像ビュワーのようなものは自分が作らなくてすでに高機能なものが出そろっています。それらの作り方が掲載されている入門書がありますが、「自分が作りたいのはこのようなソフトではない」と思い、モチベーションが低下してしまいます。(こうした文法書を書いている人たちは、本当に自力で高度なプログラムを作れるのかな?と思ったり(不遜な考えですが)もします。プログラミングの基礎をおぼえることとプログラムを作ることは別物のような気がするからです)
モチベーションが上がらない、そんな貴方に問題です。
使用言語は問いません。
まずはIDEを使わずにメモ帳にでも書いてみましょう。
【問題】
1から100までの数を表示するプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。
う~ん。これは思ったより難しいですね。白旗をあげますのでご教授ください。
static void Main(string[] args)
{
for (int x = 0; x <= 100; ++x)
{
if(x%3==0)
{
Console.Write(("Fizz").ToString());
}
else
{
Console.Write((x).ToString());
}
さて、FizzBuzz 問題は、何が難しいのでしょう?とりあえず、このプログラムの断片から想像されるのは、このプログラムを作ろうとしていた人は、「else if を知らないらしい」と想像できるかと思います。
まず、ひとつ思いつくのは、「問題文の置き換え」です。「3の倍数のとき」という問題を、コンピュータで表現できるようにしなければなりません。ここは、「3で割って余りが0の時」と、コンピュータで表現ができるようにしなければならないのです。
これができれば、「5の倍数のとき」は「5で割って余りが0の時」と置き換えができます。先のものができていれば、ここまでは簡単ですね。
static void Main(string[] args)
{
for (int x = 0; x <= 100; ++x)
{
if(x%3==0)
{
Console.WriteLine("Fizz");
}
else
{
if(x%5==0)
{
Console.WriteLine("Buzz");
}
else
{
Console.WriteLine(x);
}
}
}
}
次の難関が、「問題文の置き換え」です。ちっ!一緒になってしまった。「問題文の、順序の置き換え」ですね。
問題文は、「3の倍数の時...5の倍数の時...3と5の両方の倍数の時...」と並んでいます。これをそのままコード化すると、次のようになります。
static void Main(string[] args)
{
for (int x = 0; x <= 100; ++x)
{
if(x%3==0)
{
Console.WriteLine("Fizz");
}
else
{
if(x%5==0)
{
Console.WriteLine("Buzz");
}
else
{
if(x%3==0 && x%5==0)
{
Console.WriteLine("FizzBuzz");
}
else
{
Console.WriteLine(x);
}
}
}
}
}
で、こうすると、"FizzBuzz" は、絶対に表示されません。なぜなら、「3と5の両方の倍数」ということは、「3の倍数」でもあるため、先に "Fizz" と表示されてしまうからです。
このため、まず「3と5の両方の倍数」をチェックした後、3と5のそれぞれをチェックします。
ここで、「置き換え」が2種類発生しました。問題を「コンピュータに理解できる問題に置き換える」ことと、問題の順序を「他の判定に取られないように置き換える」ことの2つです。この置き換えが難しいのかなぁ?とか思っているのですが、どんなもんでしょう?
それとは別に、「3の倍数でかつ5の倍数」ということは「15の倍数」ですから、これも置き換えておくと若干実行速度の向上を望めるかもしれません。
おまけ。問題としては「3の倍数...5の倍数...3と5の両方の倍数...」とするより、「3の倍数...5の倍数...9の倍数...」とした方が、嵌らせ易いでしょう。つまり、9が3の倍数であることに気がつくかどうか、ということです。
static void Main(string[] args)
{
for (int x = 0; x <= 100; ++x) {
Console.WriteLine(
x % 15 == 0 ? "FizzBuzz" :
x % 5 == 0 ? "Buzz" :
x % 3 == 0 ? "Fizz" : x.ToString());
}
}
投稿日時 : 2007年11月7日 21:38