2007年5月16日水曜日

FizzBuzzまとめ

さて、5月の連休明けあたりから、巷で話題だったFizzBuzz問題ですが、自分も例に漏れず参加しておりました。本日はそれらのマトメです。

「どこで参加してたんだよ!」とツッコミを入れたくなるほど、BLOGの更新が滞っていたわけですが、他所のBLOGにコメントしてたりはするんですよねぇ…。
責任の重さの違いってとこでしょうか(ぉぃ;

自分は、へっぽこSE雑談記さんのエントリ FizzBuzz
http://blog.goo.ne.jp/yamaryu1972/e/44e38f297324893b4f1271ad19870d41
のコメントで、何ともセンスの無いコードをさらしていますが、実はこれ、剰余使用版の元ネタがあったので、実質30秒強 という時間で作成できてます(^^;

まず、剰余を使用するバージョン。
一行で書くとすればこんな感じですか。

for(int i=1; i<=100; ++i)
printf( i%15==0 ? "FizzBuzz\n" : i%3==0 ? "Fizz\n" :
i%5==0 ? "Buzz\n" : "%d\n", i );

ただ、自分は、選択肢が3つ以上あり、これからも選択肢が増えることが懸念されるような場合、三項演算子は使わない主義を貫いております。

よって、瞬間的に頭に浮かぶコードは、必然的にこんな風に。

for(int cnt=1; cnt <=100; cnt++)
{
if(!(cnt%3==0 || cnt%5==5)) printf("%d", cnt);
if(cnt%3==0) printf("Fizz");
if(cnt%5==5) printf("Buzz");
printf("\n")
}

これをベースにすると「剰余を使用しないバージョン」を作る場合は…
…もう楽チンですよね。
次のような感じで、「剰余を使わずに、倍数を判定する方法」のみを考えればOKです。
  1. 各条件毎にカウンタを用意して、ループカウンタと同じタイミングでインクリメントする。

  2. 3の倍数はカウンタの数値が3つおきに出現するので、条件カウンタが3になった場合が3の倍数と判断する。条件にカウンタが合致した場合、"Fizz"を出力し、カウンタのクリア処理を行う。

  3. 5の倍数の場合も同様に判定するものとする。

  4. 剰余を使用するバージョンの条件式を上記の条件式と置き換え、条件カウンタのクリア処理をそれぞれ追加する。

そーすると、以下のようなコードになります。

int cnt=1, fizzCnt=1, buzzCnt=1;
for(; cnt <=100; cnt++, fizzCnt++, buzzCnt++)
{
if(!(fizzCnt==3 || buzzCnt==5)) printf("%d", cnt);
if(fizzCnt==3) printf("Fizz"), fizzCnt = 0;
if(buzzCnt==5) printf("Buzz"), buzzCnt = 0;
printf("\n")
}
とりあえず、処理速度軽視、可読性重視、センス無視ってことで(^^;

この手の問題は個人の好みやコーディングスタイルが反映されるので面白いですね。
はてなブックマークから辿ってみると、色々な言語やスタイルが見れて興味深いです。

2 個のコメント:

匿名 さんのコメント...

Nice!です。Codeはね。Nextを期待していることを自覚してくれればOKです。
いやいや、良いのですよ今は...ん...
でもね...Nextを期待しています!

S-Kic さんのコメント...

コメントありがとうございます。
この口調は…S演さん、ですよね?(^^;

Nextを指すものが未だ漠然としてますが、Codeについては趣味的なものですので、そこへ留まり続ける事はございません…多分。

仕事の面では、こーいった単純な話を奥深くまで掘り下げて話すこともできるレビューアになりたいと思ってますが…なかなか実力が伴わず;

御期待に沿えるよう頑張ります。