LoginSignup
5
5

More than 5 years have passed since last update.

上と左の合計

Last updated at Posted at 2014-06-07

http://qiita.com/Nabetani/items/34bf2a05099a47e193b6
http://nabetani.sakura.ne.jp/hena/ord22irrpas/

50分ほど。かなり大変でした。
一応Ruby 1.8/2.0で動作。
nilを活用しているので同等のものがない言語への移植は困難。

hena22.rb
#!/usr/bin/env ruby
#http://qiita.com/Nabetani/items/34bf2a05099a47e193b6
#http://nabetani.sakura.ne.jp/hena/ord22irrpas/
STDOUT.sync=true
while gets
    a,b=$_.chomp.split(':')
    column,row=a.split('x').map(&:to_i)
    cells=!b ? [] : b.split(',').map{|e|
        l,t,w,h=e.split('').map(&:to_i)
        #番兵を設けるため1を足す。高さ/幅から端点の座標に変更。
        {:x1=>l.to_i+1,:x2=>l.to_i+1+w.to_i,:y1=>t.to_i+1,:y2=>t.to_i+1+h.to_i}
    }

    m=(row+1).times.map{[nil]*(column+1)}
    (row+1).times{|y|m[y][0]=0}
    (column+1).times{|x|m[0][x]=0}
    m[0][1]=1 #m[1][0]=1でも可。適当。

    while !m[row][column] # 右下が埋まるまで
        1.step(row){|y|
            1.step(column){|x|
                next if m[y][x] # 既に埋まっていたらスキップ
                #1x1のセルでなければ
                if cell=cells.find{|e|e[:x1]<=x&&x<e[:x2] && e[:y1]<=y&&y<e[:y2]}
                    #セルの右上を見ている時に限り左・上隣を見る
                    if cell[:x1]==x && cell[:y1]==y
                        cells_for_val={}
                        val=0
                        #左隣
                        unless (cell[:y1]...cell[:y2]).each{|_y|
                            adjacent_cell=cells.find{|e|e[:x1]<=x-1&&x-1<e[:x2] && e[:y1]<=_y&&_y<e[:y2]}
                            if !adjacent_cell||!cells_for_val.include?(adjacent_cell)
                                cells_for_val[adjacent_cell]=1 if adjacent_cell
                                break if !m[_y][x-1] # まだセルが埋まっていなければスキップ。breakするとeachはnilを返す。unless〜next。
                                val+=m[_y][x-1]
                            end
                        }
                            next
                        end
                        #上隣
                        unless (cell[:x1]...cell[:x2]).each{|_x|
                            adjacent_cell=cells.find{|e|e[:x1]<=_x&&_x<e[:x2] && e[:y1]<=y-1&&y-1<e[:y2]}
                            if !adjacent_cell||!cells_for_val.include?(adjacent_cell)
                                cells_for_val[adjacent_cell]=1 if adjacent_cell
                                break if !m[y-1][_x]
                                val+=m[y-1][_x]
                            end
                        }
                            next
                        end
                        #セルを埋める
                        (cell[:y1]...cell[:y2]).each{|_y|
                            (cell[:x1]...cell[:x2]).each{|_x|
                                m[_y][_x]=val%100
                            }
                        }
                    end
                else
                    next if !m[y-1][x] || !m[y][x-1]
                    val=m[y-1][x]+m[y][x-1]
                    m[y][x]=val%100
                end
            }
        }
    end
    puts "%02d"%m[row][column]
end
5
5
3

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
5
5