迷路問題解いてみた
http://d.hatena.ne.jp/hajimehoshi/20100113/1263316177
って書いてたのでリンク先の問題文だけ読んで、なんとなくrubyで解いてみた。
4時から始めて5時13分という結果でした。
どうやってとこうかなーって思って悩んだ結果、それぞれのマスを、最寄の数字+1と全て演算していくのを繰り返していけばいいやと
考えついて、求めてみたあとに、そういえば、ゴールから線引くのどうしよう。これだと何歩で歩けるって結果にならね!?
って思って後から逆順に遡るロジックを付け足しました。
なので、set_addressメソッドに、そのマスの値を更新するかどうかのオプションを追加してたりしてますね。後付で。
今改めて、http://d.hatena.ne.jp/hajimehoshi/20100113/1263316177を読んでみると、中心となる解き方は一緒の方法
使ってる…。
まるでカンニングしたみたいだ……。
一応、解き方とか読まずに、元となるアルゴリズムとか全然知識無しで自力で考えたつもりなんですが……、
説得力皆無!!
とりあえずだらだらと書いた、リファクタリングもしてないソースコードを貼っていきますね。
われながら数字用の@mapと、後付で大急ぎでつけた@str_mapとか、変数名ひどいと思います。
START = 0 CANT_GO = -1 CAN_GO = -2 GOAL = -3 X = 1 Y = 0 def get_cell(address) return @map[address[X]][address[Y]] end def addition_address(address, diff) return [address[Y] + diff[Y], address[X] + diff[X]] end def set_address(address, update_flg = true) min = nil min_diff = nil [[-1, 0], [0, -1], [1, 0], [0, 1]].each do | diff | get_value = get_cell(addition_address(address, diff)) if get_value >= START && ( min.nil? || min > get_value ) min = get_value min_diff = diff end end if min && update_flg @map[address[X]][address[Y]] = min + 1 end return min_diff end start_address = [] goal_address = [] @map = [] @str_map = [] #map展開 open("input.txt").each do |str| row = [] str.split(//).each do | cell | case cell when " " row << CAN_GO when "S" start_address = [row.size, @map.size] row << START when "G" goal_address = [row.size, @map.size] row << GOAL when "*" row << CANT_GO end end @map << row @str_map << str.split(//) end p @map y_max = @map.size x_max = @map[0].size while get_cell(goal_address) == GOAL y_max.times do | y | x_max.times do | x | if get_cell([x, y]) < CANT_GO set_address([x, y]) end end end p @map end current_address = goal_address while current_address != start_address diff = set_address(current_address, false) current_address = addition_address(current_address, diff) @str_map[current_address[X]][current_address[Y]] = '$' if current_address != start_address end puts @str_map.map{|cols| cols.join}.join