第一回 オフラインリアルタイムどう書く( http://atnd.org/events/30285 )。
問題は http://nabetani.sakura.ne.jp/hena/1/
計算手順としてもちょっと趣向を変えつつ、groovy で。
groovy
def side = { [ 'o', 'x' ][it%2] }
def xy={ [it.intdiv(3),it%3] }
def sub={a,b->[ a[0]-b[0], a[1]-b[1] ] }
def onLine={a,b,c->
bp=sub( xy(b), xy(a) )
cp=sub( xy(c), xy(a) )
bp[0]*cp[1] == bp[1]*cp[0]
}
def someLine={ b, hand->
for( p in (0..<b.size())){
for( q in (0..<p)){
if ( onLine( hand, b[p], b[q] ) ){
return true;
}
}
}
false;
}
def solv={ q->
b=[[],[]]
for( ix in (0..<[ 9, q.size() ].min())){
hand=q[ix].toInteger()-1
if ( b.any{ it.contains(hand) } ){
return "Foul : ${side(ix+1)} won."
} else if ( someLine(b[ix&1], hand ) ){
return "${side(ix)} won."
}
b[ix&1].add(hand)
}
"Draw game."
}
[
"79538246","35497162193","61978543","254961323121","6134278187",
"4319581","9625663381","7975662","2368799597","18652368566",
"965715","38745796","371929","758698769","42683953",
"618843927","36535224","882973","653675681","9729934662",
"972651483927","5439126787","142583697","42198637563","657391482"
].each{ println( solv( it ) ) }
もう少し簡潔に書ける気がしてならないが、まあこんなところ。
まだまだ慣れてないので、ブロックから return で抜けても関数から抜けないとか、後置 if がないとか、その辺りでやられる。
ブロックから return で抜けても関数から抜けないので、ruby ではほとんど書くことがない for 文を書かざるをえない(と思う)のが新鮮。
ruby よりいいなぁと思うのは、a..<b
のような範囲演算子とか、{ [ 'o', 'x' ][it%2] }
で使っている it 辺り。
ポイントは、[0,1,2],[3,4,5]
のようなデータを持っていないところ。
しかし、シンタックスハイライトがつかないのが残念。