第25回オフラインリアルタイムどう書く「めぐるセル」の rubyによる実装
問題 http://nabetani.sakura.ne.jp/hena/ord25rotcell/
解答リンク集 http://qiita.com/Nabetani/items/636fce060e1ebbc95f9b
イベント http://yhpg.doorkeeper.jp/events/13947
当日お見せした実装。
module RotCell
class Rotater
def initialize(board)
@board = board
end
def rot_core(ix, cx, cy)
ix = ix.sort_by{ |i|
y, x = i.divmod(5)
Math.atan2(y - cy, x - cx)
}
v = @board.values_at(*ix)
v.size.times.each do |i|
@board[ix[i]] = v[i - 1]
end
end
def rot(cmd)
positions = cmd.chars.map { |c| @board.index(c).divmod(5) }
left, right = positions.map { |xy| xy[1] }.minmax
top, bottom = positions.map { |xy| xy[0] }.minmax
indices_from = @board.size.times.select{ |xy|
y, x = xy.divmod(5)
(((x == left - 1 || x == right + 1) && ((top - 1..bottom + 1) === y)) ||
((y == top - 1 || y == bottom + 1) && ((left - 1..right + 1) === x)))
}
rot_core(indices_from, (left + right) / 2r, (top + bottom) / 2r)
indices_from.map { |ix| @board[ix] }.sort.join
end
end
def self.solve(s)
cells = ('a'..'y').to_a
commands = s.split(',')
ro = Rotater.new(cells)
commands.each do |c|
ro.rot(c)
end
r = ro.rot(commands[-1])
r.empty? ? 'none' : r
end
end
DATA.map do |line|
id, src, expected = line.split(/\s+/)
actual = RotCell.solve(src)
ok = actual == expected
puts '***NG*** : %s %s->%s ( %s )' % [id, src, actual, expected] unless ok
ok
end.all?.tap { |r| puts ( r ? 'ok' : 'NG') }
__END__
0 ab,gg,uj,pt,an,ir,rr hpqsvwxy
1 gs,ok abcdftvwxy
2 gs,sg,ok none
いつも通り、テストデータの大半は省略。
実装戦略で選択はいくつかあって。
- データの持ち方
a) 盤面を2次元または1次元の配列で持つ
b) 文字と座標の対応を、key-value pair で持つ - 回転関連
p) 回る方向にそってセルを集める
q) 適当に集めて、あとで整列する
あたりが重要だと思う。
で。
この実装は aq という戦略にした。
会場では ap と bp の方がいらっしゃったけど q を選んだ方はいなかった。
ruby なので minmax
や divmod
の結果を多重代入で取得とか、ary[-1]
が ary.last
と同等であることを利用するとか、そういう小ネタを積み重ねている。
全体的に美しくない実装だと感じてはいるものの、こんな感じで。
ruby に偏っているので別の言語でいくべきだったなぁと思ったり。
Author And Source
この問題について(第25回オフラインリアルタイムどう書く「めぐるセル」の rubyによる実装), 我々は、より多くの情報をここで見つけました https://qiita.com/Nabetani/items/17f7844d75f3613da28a著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .