神奈川Ruby会議 01
に参加しました。
これは、rubyのユーザーやコミッターの皆さんが、ノートPCでプログラミングをしたり、rubyとどう関わっていくかなど話し合ったりする、賑やかな大会でした。
ちょっと気になったのは、皆さんが使っているPCです。見て回ると、やはりマックが多かった。8割くらいはマックでした。マックを買ったのが間違いでなくてよかった。
この会議の一番初めの内容が「ペアプロ大会」でした。
rubyはほとんどプログラムを書いたことがないので、ちょっと不安でしたが、とても勉強になりました。エディターの使い方も慣れていなかったのですが、パートナーになってくれた方がいろいろと教えてくださいました。
お題は、「計算機」です。
文字列を与えると、それを計算するプログラムです。
ただし、演算子の優先順位がrubyのその順番と違います。
rubyでは、優先順位が高い方から低い方に
”*”、”+”、”&”、”|”
ですが、この計算機は、高い方から低い方に
”|”、”&”、”+”、”*”
という計算機です。つまり優先順位がrubyと逆です。たとえば、
4*5+6&7|8
は、ruby では
なので
(((4*5)+6)&7)|8
なので
10
ですが、この計算機では 4*(5+(6&(7|8)))
という順番になるので
44
です。
まず作ったプログラムは、
def calc(form)
tmp1 = 1
form.split("*").each do |form1|
tmp2 = 0
form1.split("+").each do |form2|
tmp3 = 0xFFFFFFFF
form2.split("&").each do |form3|
tmp3 &= eval form3
end
tmp2 += tmp3
end
tmp1 *= tmp2
end
def calc2(form)
form.split("*").inject(1) do |memo1, form1|
memo1 * form1.split("+").inject(0) do |memo2, form2|
memo2 + form2.split("&").inject(-1) {|memo3, form3| memo3 & eval(form3)}
end
end
end
tmp1 = 1
form.split("*").each do |form1|
tmp2 = 0
form1.split("+").each do |form2|
tmp3 = 0xFFFFFFFF
form2.split("&").each do |form3|
tmp3 &= eval form3
end
tmp2 += tmp3
end
tmp1 *= tmp2
end
return tmp1
end
です。動くことは動いたけど、rubyらしさがあまり感じられない。
「"inject" というメソッドがありますよ」って教えてもらい、それで書き換えました。
form.split("*").inject(1) do |memo1, form1|
memo1 * form1.split("+").inject(0) do |memo2, form2|
memo2 + form2.split("&").inject(-1) {|memo3, form3| memo3 & eval(form3)}
end
end
end
これで、ちょっとかっこよくなった。
でも、よく見ると基本的に同じ構造が続いているので、もう一工夫できそう。
ある人が、すでに書いていて、
こんなのがありました。
def
calc(s,o='*+&|')s.split(o[0]).map{|s|o=='|'?s.to_i: calc(s,o[1,3])}.reduce(o[0])
end
calc(s,o='*+&|')s.split(o[0]).map{|s|o=='|'?s.to_i: calc(s,o[1,3])}.reduce(o[0])
end
す、すごすぎる。
これ以外も、たくさん実装例がありました。
素晴らしい。
勉強になりました。
関係者の皆さま、大会運営お疲れ様でした。ありがとうございました。
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓