octech このページをアンテナに追加 RSSフィード

2007-05-18 頭の体操になるか?

[]FizzBuzz問題 15:15 FizzBuzz問題を含むブックマーク

FizzBuzz問題を解く

もともとの記事はこれ↑らしい。

それに対していろいろな反応があって、ちょっと外側から面白がっていた。

google:FizzBuzz問題, google:FizzBuzzテスト

問題そのものは前に見たことあって、見た瞬間書けそうだったので書かないでいたけど、ちょっとダメらしい人がやっぱりいるとの書き込みなどをちょっと見たりして、「もしかしてなんかオチがあるのか??」と自分のことも心配になり、Rubyで書いてみた。

  • 新規テキストファイルを開き、問題文をコピペするのに30秒程度。
  • Range機能を使ったことがなかったけど、あいまいな記憶のままに書いたら間違っていて、Range機能をググって確認するのに1分弱。
  • to_sメソッドもあいまいな記憶のままに書いたらtosと覚えていたらしく、その確認に1分弱。
  • 後は実際のコーディングで、やると決めてから完了まで5分弱でした。

って、最初に思い浮かんだコードのままでほとんど問題なしでした。うーん、これがたとえば15分かかっても書けない人とは同等に仕事できないよね。30分かかっても出来ない人は同じプロジェクトにプログラマとしていてほしくない。

もしかして使う言語によって差があるのかな?

### fizzbuzz.rb ###

# 1から100までの数をプリントするプログラムを書け。
# ただし3の倍数のときは数の代わりに「Fizz」と、
# 5の倍数のときは「Buzz」とプリントし、
# 3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

print "=== FizzBuzz ===\n"

for i in 1..100 do
  str = ""
  if i%3==0
    str += "Fizz"
  end
  if i%5==0
    str += "Buzz"
  end
  if str == ""
    str = i.to_s
  end
  print str + "\n"
end

FizzBuzz問題を解く#2

FizzBuzz問題について、はてダのanonymous diaryに上がっていたのだが、これが面白い。

FizzBuzz問題

通常の問題に「ただし、剰余(Rubyでいう % 演算子や modulo)を使うな。」という制限が加えられていた!

おぉー、これは面白そう〜。と、1分少々考えて計3,4分で上記コードを修正して書いたのが次のコード。

まぁ、最低レベルだろうな。

# 1から100までの数をプリントするプログラムを書け。
# ただし3の倍数のときは数の代わりに「Fizz」と、
# 5の倍数のときは「Buzz」とプリントし、
# 3と5両方の倍数の場合には「FizzBuzz」とプリントすること。
#
# *** ただし剰余は使うな ***
#

print "=== FizzBuzz2 ===\n"

c3 = 0
c5 = 0
for i in 1..100 do
  str = ""

  c3 += 1
  if c3==3 then
    str += "Fizz"
    c3 = 0
  end

  c5 += 1
  if c5==5 then
    str += "Buzz"
    c5 = 0
  end

  if str == ""
    str = i.to_s
  end
  print str + "\n"
end

[][]FizzBuzz, short code 18:37 FizzBuzz, short codeを含むブックマーク

short codeへの入り口

anarchy golf

id:tattyu氏にショートコードのランキングサイトがあることを教えてもらった。ここにはたくさんの問題とそれに対してのショートコードのランキングが載せられる。

ログイン認証などもなく、Code Golfほどシリアスではないのでカジュアルに楽しめそう。

anarchy golf - FizzBuzz

試しに前述のコードを短くしてアップしてみた。

(1..100).each{|i|s='';s='Fizz'if i%3==0;s+='Buzz'if i%5==0;s=i.to_s if s=='';print s+"\n"}

ファイルサイズを小さくするのが優先なので、CR+LFの改行を外し、セミコロンに置き換えて90byte。

ちなみに、改行を入れたら以下のようになる。

(1..100).each{|i|
  s=''
  s='Fizz'if i%3==0
  s+='Buzz'if i%5==0
  s=i.to_s if s==''
  print s+"\n"
}

これで45位・・。

f:id:octech:20070518183538j:image

うーん、何を短くすればいいのか?アルゴリズムを改良か?

あ、やべ・・。

これ、ハマるわ・・。

step 2

ふと気づいたのが出力方法。

print だと改行コードも足さないといけない。しかし p ではダブルクォーテーションで括られてしまう。他になかったっけ?と思って思い出したのが、puts。

プログラミング言語 Ruby リファレンスマニュアル .. putsの説明

これでマイナス6byte!

(1..100).each{|i|s='';s='Fizz'if i%3==0;s+='Buzz'if i%5==0;s=i.to_s if s=='';puts s}

submitしてみたら、84byteで39位!

f:id:octech:20070518193648j:image

仕事が、仕事が、と言いながらもこんなことやってちゃダメだ、俺!

続きは明日!

と書いてしまえば大丈夫かな。

step 3

ちょっと仕事の区切りが付いたので、自分へのご褒美としてshort coding time!

三項演算子を使う仕組みに変えて書いてみたらサクッと減った!

(1..100).each{|i|puts i%3==0?i%5==0?"FizzBuzz":"Fizz":i%5==0?"Buzz":i.to_s}

でsubmitしたら37位〜。

f:id:octech:20070518210604j:image

tattyutattyu 2007/05/21 20:49 Luaだと変な制約が多くて減らすのがしんどいです

octechoctech 2007/05/24 15:04 Lua、全然知らないけど、変な制約って何があるの??

tattyutattyu 2007/05/24 16:01 ifを使うとthenが必要なのとか、0だとtrueとして処理されてしまうとか(余りが0の時やばい)、論理演算子は3項演算子みたいな挙動だったりですね。Luaで77バイトとかどうやってるのか想像もつきません。。。

octechoctech 2007/05/24 21:21 うーん、0がtrueになるとか面倒だね。そういうのを逆手にとると短くなる可能性が、あるのかな?