Yokohama.rb Monthly Meetup #70 :: どう書く

Yokohama.rb Monthly Meetup #70に行って「どう書く」に挑戦してきた。

問題はこれで、自分の回答は下に記載。 回答時間は20分いかないぐらいだったと思うんだけど、競技プログラミング勢なら10分かからないだろうとのこと。

もっとキレイに書きたかった & 1次元配列 + 番兵での回答は思いつきもしなかったので悔しみがある。

class Walker
  attr_reader :dir, :point

  def initialize(point)
    @point = point
    @dir = 'd'
    @ended = false
  end

  def ended?
    @ended || i < 0 || i > 3 || j < 0 || j > 3
  end

  def i
    point[0]
  end

  def j
    point[1]
  end

  def move(type)
    case type
    when 0
      case dir
      when 'r' then up
      when 'u' then right
      when 'l' then down
      when 'd' then left
      end
    when 1
      case dir
      when 'r' then down
      when 'u' then left
      when 'l' then up
      when 'd' then right
      end
    when 2
      case dir
      when 'r' then right
      when 'u' then up
      when 'l' then left
      when 'd' then down
      end
    when 3
      @ended = true
    end
  end

  def name
    ('a'..'p').to_a[(i * 4) + j]
  end

  private

  def up
    @point = [i - 1, j]
    @dir = 'u'
  end

  def down
    @point = [i + 1, j]
    @dir = 'd'
  end

  def right
    @point = [i, j + 1]
    @dir = 'r'
  end

  def left
    @point = [i, j - 1]
    @dir = 'l'
  end
end

def solve(tiles)
  map = tiles.split('/').map {|x| x.split('').map(&:to_i) }
  point = [0, 1]
  w = Walker.new(point)
  a = []
  while true
    break if w.ended?
    a << w.name
    w.move(map[w.i][w.j])
  end
  a.join
end

raise unless solve('0113/1201/2201/2100') == 'bcgfeabfjnoklpo'
raise unless solve("2110/2013/2210/0122") == "bcgh"
raise unless solve("2222/2130/2121/2002") == "bfg"
raise unless solve("0021/2212/2102/1220") == "baeimnoplhdcbfjkgfe"
raise unless solve("0213/1221/0220/1103") == "bfjnokgcbaefghlkjimn"
raise unless solve("3201/3120/3333/3333") == "bfghdcgk"
raise unless solve("3233/3233/3133/3333") == "bfjk"
raise unless solve("3333/3333/3333/3333") == "b"
raise unless solve("1212/1201/2123/2220") == "bfjkl"
raise unless solve("2212/3102/1002/2100") == "bfgcba"
raise unless solve("0023/2221/1102/0031") == "baeijnm"
raise unless solve("1121/3120/0212/1120") == "bcdhgfba"
raise unless solve("2202/3211/2120/1210") == "bfjklhgcd"
raise unless solve("3201/3211/1111/0100") == "bfjkonjie"
raise unless solve("0121/1120/1111/1211") == "bcdhgfbaefjkop"
raise unless solve("1212/1213/2103/0213") == "bfjkgfea"
raise unless solve("1121/2212/1323/3031") == "bcdhl"
raise unless solve("0030/1230/1121/0031") == "baefg"
raise unless solve("2223/1211/0002/1200") == "bfjimnokl"
raise unless solve("3210/0033/0201/0130") == "bfei"
raise unless solve("0213/2220/0021/3002") == "bfjim"
raise unless solve("2121/2112/1110/1010") == "bcdhlkgfba"
raise unless solve("0113/1003/2303/2220") == "bcgfj"
raise unless solve("2202/1110/1302/0313") == "bfgkj"
raise unless solve("1211/3202/2102/0222") == "bfjkgh"
raise unless solve("3113/0002/0112/1022") == "bcgfjko"
raise unless solve("1200/3000/0121/0121") == "bfe"
raise unless solve("2221/1122/1031/2200") == "bfgh"
raise unless solve("1202/0121/0222/1300") == "bfghlpo"
raise unless solve("0002/1012/1021/3300") == "baefbc"
raise unless solve("0211/1200/2220/2103") == "bfjnokghdc"