LoginSignup
2
0

More than 3 years have passed since last update.

Rails on Tiles(どう書く)

Posted at

与えられたタイルのレールに沿って移動するとき、範囲外にはみ出てしまうまでのルートを求める問題です。

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はタイルの位置を数字で表しているので、最後にアルファベットに変換しています。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0