Tetris in anagol

kskさんに大敗。
kskさんのコードがやってることとやってることがほとんど同じはずのボクのコードがこんなにも長いのはどうしてだろーわー。
やってることはお互いに、

  • "#"を四つ見つけて、それをスペースに置き換える
  • さらにそこからN文字先のスペースを"#"にかえる
  • "#"だけで構成されている行を消すという

まあつまりそういうことなんですが。向こうのほうがうまいなー。
入力をひとつの文字列として$_に代入したあとで、最初の二つをeval部分で処理しています。

eval"sub /#(.{%d}) /m,' \\1#';"%"x\x83A"[~/#//4]*4

~/#//4は、「($_ =~ /#/)/4」で、最初の#のある位置を4で割ってます。これは各サンプルに対して[0,2,1]を返します。
"x\x83A"は、各サンプルで#を落とす「距離」が埋め込んであって、120,131,65が入ってます。一行の長さ×行数-1で、11*11-1,11*12-1,11*6-1です。
たとえば最初のインプットなら、結局は…

sub /#(.{120}) /m,' \\1#'
sub /#(.{120}) /m,' \\1#'
sub /#(.{120}) /m,' \\1#'
sub /#(.{120}) /m,' \\1#'

となって、4つの#に対して#の落下が処理されるわけです賢いなー賢いなー。
次は#だけで構成されている行を消して、消した分だけ足さないといけません。こいつはgrepがやってます。

gsub(/
#+$/m){puts" "*10}

正規表現で#だけの行を見つけて、そのたびにputs" "*10してるわけですが、putsの返すnilがto_sによって""になるので、置換されてまあうまいこと消えるという。
あとは落下と消去の操作をされた$_をprintで出力するだけ。
うーんsubの置換だけで落としちゃうのがポイントだったんだなー。