十字の壁がそそり立つ世界の中を君は螺旋状に歩く 横へな 2015.2.7 問題
問題
十字の壁がそそり立つ世界の中を君は螺旋状に歩く 横へな 2015.2.7 問題
結果
(´・ω・`)
ふりかえり
よかった点
悪かった点
- ガリガリ書きすぎてとてもナイーブな実装になった
- いまいち問題の本質がわかってなかった感じがある
- ↑ガリガリ書くのもマージナルな場所からガリガリ書いてしまったせい
- ↑こういうのは結局使わない「不要なコード」が増えがち("You ain't gonna need it!")
最終回答
時間制限後に直した点
debug_show_meiro
メソッドのselect
とmap
の誤りを修正debug_show_meiro
メソッドの名前を変更 ->debug
- 二方向を壁に囲われていた場合の処理を追加。ついでにリファクタリング
- 問題文の座標系と
@field
配列のindex
がグラフィカルに対応してなかったのを修正 DIR
がただの文字列でも良さそうだったので修正。ついでにシンボル化。@field
が特に配列である必要がなかったのでhashに変更- 目についたデバッグ用メソッド・メンバ削除
その他いろいろ(あんまり覚えてない)
実コード
class Wall attr_accessor :field MAX = 100 def initialize(input) n, e, s, w = input @field = {} s = -s w = -w s.upto(n) do |y| set_wall(0, y) end w.upto(e) do |x| set_wall(x, 0) end end def is_wall(x, y) key = key_of(x, y) @field[key] end def set_wall(x, y) key = key_of(x, y) @field[key] = true end private def key_of(x, y) half = MAX / 2 x = x + half y = half - y if x < 0 || x >= MAX || y < 0 || y >= MAX debug end return "#{x},#{y}" end end class Person attr_reader :point VECT = [[ 0, 1], [ 1, 0], [ 0, -1], [-1, 0]] DIR = :NESW def initialize(w) @wall = w @point = [1, 1] @wall.set_wall(1, 1) @front = 1 end def step v = VECT[togo_dir] nx, ny = add_point(v) @wall.set_wall(nx, ny) @point = [nx, ny] end def togo DIR[togo_dir] end private def right (@front + 1) % 4 end def left (@front + 3) % 4 end def try_step(x, y) !@wall.is_wall(x, y) end def togo_dir v = VECT[right] nx, ny = add_point(v) if try_step(nx, ny) @front = right return @front end v = VECT[@front] nx, ny = add_point(v) if try_step(nx, ny) return @front end return left end def add_point(v) x = @point[0] + v[0] y = @point[1] + v[1] return x, y end end class Solver attr_writer :input def solve arr = @input.split(",") arr[3],day = arr[3].split(":") arr.map!{|e| e.to_i} d = day.to_i w = Wall.new(arr) me = Person.new(w) d.times do me.step end me.togo end end
require "./solver.rb" module Test def self.exec all_ok = true File::open("./input.txt") do |f| f.each do |line| arr = line.split("\t") s = Solver.new s.input = arr[1].chomp expected = arr[2].chomp actual = s.solve.chomp is_ok = expected == actual all_ok = all_ok && is_ok next if is_ok puts "case#{arr[0]} actual=#{actual} expected=#{expected}" end end if all_ok puts "-> ALL OK" else puts "-> OMG" end end end Test.exec