せかいや

いまいるここを、おもしろく http://sekai-in-the-box.appspot.com/

【Ruby】【アルゴリズム】番兵法(壁がある場合のプロット)。都度出力

 

最強最速アルゴリズマー養成講座の問題を解いてるよ

アルゴリズムだんだん面白くなってきた。
実現したいことがコーディングできるようになると、ハードルが下がってくる。

問題(一部変更)

縦の長さがheight、横の長さがwidthのマス目で構成された盤面があります。このマス目の中に適当に石を置きます。この時、石を入れたマス目の中心の距離がちょうど2マス分だけ離れたマスに石を置くことはできません。
0,0マスから順に石を置いていく施行を繰り返し、結果のボードを表示しなさい

ちょっと日本語が不自然だけど。

ポイント

番兵法を使ってボードの枠を+2づつ拡大する

"○"と"×"を置いていく(nil ○ × の3状態)のではなく、
履歴の○の状態から「ここに○が置けるか」だけ判断する
 

いけてないコード

まずは自分が書いたコード↓

def max_stones(width, height)
  map= Array.new(height+4).map! { Array.new(width+4) }
  2.step(height+1) do |h|
    2.step(width+1) do |w|
        if map[h][w].nil?
        map[h][w] = "○" 
        map[h-2][w] ||= "+"
        map[h][w-2] ||= "+"
        map[h+2][w] ||= "+"
        map[h][w+2] ||= "+"
      end
    end
  end
  map.each{|line| p line.map!{|x| x ||="+"}.join("")}
end
max_stones(10,20)

 

2.step(height+1) do |h|

がポイント。
 
■実行結果

"++++++++++++++"
"++++++++++++++"
"++○○++○○++○○++"
"++○○++○○++○○++"
"++++○○++○○++++"
"++++○○++○○++++"
"++○○++○○++○○++"
"++○○++○○++○○++"
・・・

壁まで出力されちゃう。


 

掲載されてるコード

def max_stones(width, height)
  map= Array.new(height+4).map! { Array.new(width+4, 0) }
  2.step(height+1) do |h|
    2.step(width+1) do |w|
      if map[h-2][w] == 0 && map[h][w-2] == 0
        map[h][w] = 1 
        print "○"
      else
        print "+"
      end
    end
    print "\n"
  end
  map.each{|line| p line}
end
max_stones(10,20)

なるほど。
都度出力するという手もあるのか。

それに、値を入れるたびに4方面に×をつけるのではなくて
上と左がわに○がついていなかったら、○を置く、のほうがシンプルで良い。


なるほどー。。