オフラインリアルタイムどう書く E12 の ruby による実装例

  • 1
    Like
  • 4
    Comment

問題:http://mtsmfm.github.io/2017/03/04/doukaku-e12.html
解答リンク集:http://qiita.com/mtsmfm/items/d307c7b884cd86621262

require "benchmark"

TETS={
  "I"=>[0..3],
  "L"=>[0..2, 0..0],
  "O"=>[0..1, 0..1],
  "S"=>[0..0, 0..1, 1..1],
  "T"=>[1..1, 0..1, 1..1]
}

def impl( pos )
  field=Hash.new{ |h,k| h[k]=0}
  pos.each do |n,name|
    tet = TETS[name]
    y=(0...tet.size).inject(0){ |acc,tx|
      [acc,field[tx+n] - tet[tx].min].max
    }
    tet.each.with_index(n) do |t,tx|
      field[tx] = y+t.max+1
    end
  end
  field.values.max
end

def solve( src )
  impl(src.scan( /(\d+)(\D)/ ).map{ |n,t| [n.to_i,t] }).to_s
end

$stdout.sync=true

DATA.map do |line|
  /(?<num>\w+)\s+(?<src>\S+)\s+(?<expected>\S+)/=~line
  actual = nil
  tick = Benchmark.realtime{  actual = solve( src ) }
  okay = actual==expected
  puts( "%s %s %s->%s ( e:%s ) tick=%.3f" % [ ( okay ? "ok" : "**NG**" ), num, src[0,70], actual, expected, tick] )
  okay
end.all?.tap{|x| puts( x ? "everything is ok" : "something wrong" ) }

__END__
0 1O3L0I0T  5
1 0I  4
20  999I999I999I999I999I999I999I999I999I999I999I  44 

テストデータの大半は省略。

フィールドの表現は、x座標をキーにして、天井の高さを値にした Hash にした。
それに合わせて、テトロミノの表現も、下端と上端のペアの配列にした。
図を描く都合があったら選べない表現だけど、今回は出題者ではないのでこれでよい。
あと。回転がないからえらべる表現でもある。

所要時間は 三十数分。くだらないバグにハマってしまった。