何となく Blog by Jitta
Microsoft .NET 考

目次

Blog 利用状況
  • 投稿数 - 761
  • 記事 - 18
  • コメント - 36196
  • トラックバック - 222
ニュース
  • IE7以前では、表示がおかしい。div の解釈に問題があるようだ。
    IE8の場合は、「互換」表示を OFF にしてください。
  • 検索エンジンで来られた方へ:
    お望みの情報は見つかりましたか? よろしければ、コメント欄にどのような情報を探していたのか、ご記入ください。
It's ME!
  • はなおか じった
  • 世界遺産の近くに住んでます。
  • Microsoft MVP for Visual Developer ASP/ASP.NET 10, 2004 - 9, 2011
広告

記事カテゴリ

書庫

日記カテゴリ

ギャラリ

その他

わんくま同盟

同郷

 

わんくま祭り化してきた感のある「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
コメント
  • # re: FizzBuzz 問題:難しいのはどこか
    裏口
    Posted @ 2007/11/08 10:25
    他のメンバーの方もそれぞれの視点で取り上げてますが、個人的にはこのエントリーを最も好みます。
    # 問題の原点(本質)を捕らえているという意味で、です。

    他の方の取組みにもそれなりの面白さはありますが、なんとなく違和感を感じてしまう。

    # 全てを見ているわけではありませんので不快に思われたら
    # お詫びしますが・・・。
  • # re: FizzBuzz 問題:難しいのはどこか
    凪瀬
    Posted @ 2007/11/08 15:22
    プログラムが「自分で」書けるようになるための重要なポイントですね。
    今となっては何時乗り越えたかも覚えていない壁ではありますが
    業界の裾野を広げるにはこの壁は何かをよく検討しておく必要があると思っています。

    FizzBuzzの場合はやっぱり15の倍数の部分をうまく処理できるかどうかでしょうかねぇ。
    ここをFizzでいいよ、とすればかなり難易度は低いので好けども。
  • # re: FizzBuzz 問題:難しいのはどこか
    がる
    Posted @ 2007/11/09 0:23
    どもです。
    正直。初めて見たときは「2分かぁ…typoをどうやって防ぐかかな?」とかかなり見当違いな事を考えてましたが。
    最近「3の倍数は3のmodで0ならよい」「modは大抵の言語で%演算子が使える」ってところにかけらも思い至らずに硬直する若い子がいる事を知り………少々困惑気味です。

    何がわからなくてどうわからなくてどう教えればよいのか、正直、皆目検討つきませぬ orz
  • # re: FizzBuzz 問題:難しいのはどこか
    Jitta
    Posted @ 2007/11/09 7:30
    勉強が嫌いで就職したはずなのに、(広い範囲のといういみで)一番勉強が必要な業界に就職してしまったのではないかと思う、今日この頃

    壁ですか
    何が壁だったんだろう?
    のらりくらりとかわしてきた気がする(^_^;
    教育要項をみる限り、ゆとり教育がそれまでと比べて良いと思うことに、教科の連携があります
    それまで、数学と物理は切り離して教えていました
    ゆとり教育では、総合学習の時間を利用して、複数教科の関連を教えることができます
    (実際は、ハッピーマンデーで潰された月曜の時間補充に使われることが多いようですが)
    そういった連携で、問題を様々な視点から眺める癖がつけばいいのになぁ
  • # re: FizzBuzz 問題:難しいのはどこか
    Jitta
    Posted @ 2007/11/09 7:35
    「3と5の倍数の時」という条件を出さず、反対に質問ができるということを答えの一つとするのもいいかも
  • # What's up, all is going fine here and ofcourse every one is sharing information, that's in fact good, keep up writing.
    What's up, all is going fine here and ofcourse eve
    Posted @ 2019/04/08 1:00
    What's up, all is going fine here and ofcourse every one
    is sharing information, that's in fact good,
    keep up writing.
  • # Good day! I could have sworn I've been to this website before but after checking through some of the post I realized it's new to me. Nonetheless, I'm definitely glad I found it and I'll be bookmarking and checking back often!
    Good day! I could have sworn I've been to this web
    Posted @ 2019/04/09 16:37
    Good day! I could have sworn I've been to this website before but after
    checking through some of the post I realized it's
    new to me. Nonetheless, I'm definitely glad I found it and I'll be bookmarking
    and checking back often!
  • # If some one wishes expert view about blogging and site-building then i advise him/her to go to see this weblog, Keep up the pleasant job.
    If some one wishes expert view about blogging and
    Posted @ 2019/08/14 15:16
    If some one wishes expert view about blogging and site-building then i advise him/her to go to see this weblog, Keep
    up the pleasant job.
タイトル
名前
Url
コメント