与えられたタイルのレールに沿って移動するとき、範囲外にはみ出てしまうまでのルートを求める問題です。
Ruby
module RailsOnTiles
Tiles = [[2, 3, 0, 1], [1, 0, 3, 2], [3, 2, 1, 0]]
Dirs = [[0, -1], [1, 0], [0, 1], [-1, 0]]
module_function
def go(input)
field = input.chars.map(&:to_i).each_slice(3).to_a
solve(field).map { |i| ("A".."I").to_a[i] }.join
end
def solve(field, x=1, y=-1, dir=2, route=[])
dx, dy = Dirs[dir]
x += dx
y += dy
return route if x < 0 || x > 2 || y < 0 || y > 2
rev = Tiles[0][dir]
nxt = Tiles[field[y][x]][rev]
tile_num = y * 3 + x
solve(field, x, y, nxt, route + [tile_num])
end
end
if __FILE__ == $0
require 'minitest/autorun'
describe 'RailsOnTiles' do
[
["101221102", "BEDGHIFEH"],
["000000000", "BEH"],
["111111111", "BCF"],
["222222222", "BAD"],
["000211112", "BEFIHEDGH"],
["221011102", "BADGHIFEBCF"],
["201100112", "BEHIFCBADEF"],
["000111222", "BEFIH"],
["012012012", "BC"],
["201120111", "BEDABCFI"],
["220111122", "BADEHGD"],
["221011022", "BADG"],
["111000112", "BCFIHEBA"],
["001211001", "BEFI"],
["111222012", "BCFEHIF"],
["220111211", "BADEHI"],
["211212212", "BCFEBAD"],
["002112210", "BEFC"],
["001010221", "BEF"],
["100211002", "BEFIHG"],
["201212121", "BEFCBAD"]
].each do |input, expect|
it input do
assert_equal RailsOnTiles.go(input), expect
end
end
end
end
field
はタイルの配置を表していて、タイルの種類はTiles
に格納してあります。方向の種類は、0,1,2,3 がそれぞれ上右下左を表します。前のタイルから下へ行けば、次のタイルでは上から来るという具合に「反転」するので、それがrev
に入ります。あとは、field
を外れるまで再帰し、結果を返します。
なお、道すじroute
はタイルの位置を数字で表しているので、最後にアルファベットに変換しています。