鶏頭のプログラム

Ruby, Javascript, C言語, SQLなどのプログラミング

人材募集企画 2011年版を解いてみた

ぷりんさんのプロフィール - はてなさんの記事を見て
自分ならどう書くかなと試してみました。

内容はこちら


ぷよぷよの問題(人材募集企画 2011年版 問題2)をC++解いてみました。 - Gobble up pudding

試験内容はこちら

人材募集企画 2011年版: 人生を書き換える者すらいた。

プログラミング言語: Ruby
所要時間: 1時間ちょい

正直速度面ではループが多いため少し遅い気がします。
最適解とは言いがたいですが、まずまずと言ったところでしょうか。
追記:ちょっと修正しました。

N=0
G=1
Y=2
R=3
CHECKED=4

class PuyoPuyo
  def initialize list
    @list = list
  end

  def delete chain = 1
    clone = Array.new 
    @list.each{|line| clone << line.clone }
    points = get_del_points(clone)
    return if points.length == 0
    points.each{|point|
      point[0].upto(@list.length - 1){|n|
       @list[n][point[1]] = @list[n + 1] ? @list[n + 1][point[1]] : N
      }
    }
    show chain
    delete chain + 1
  end

  def get_del_points list
    del_points = Array.new
    0.upto(list.length - 1){|n|
      0.upto(5){|m|
        c = list[n][m]
        next if c == N || c == CHECKED
        list[n][m] = CHECKED
        points = check_all_side(c, n, m, list)
        next if(points.length < 4)
        del_points += points
      }
    }
    del_points.sort! {|a, b| b[0] <=> a[0] }
    return del_points
  end

  def check_all_side c, n, m, list
    points = Array.new
    points << [n,m]
    # 下
    if n != 0 && list[n-1][m] == c
      list[n-1][m] = CHECKED
      points += check_all_side(c, n-1, m, list)
    end

    # 上
    if n+1 < list.length && list[n+1][m] == c
      list[n+1][m] = CHECKED
      points += check_all_side(c, n+1, m, list)
    end

    # 左
    if m != 0 && list[n][m-1] == c
      list[n][m-1] = CHECKED
      points += check_all_side(c, n, m-1, list)
    end

    # 右
    if list[n][m+1] == c
      list[n][m+1] = CHECKED
      points += check_all_side(c, n, m+1, list)
    end
    return points
  end

  def show chain
    p '-------------------------'
    p "#{chain}連鎖"
    p '-------------------------'
    (@list.length - 1).downto(0){|n|
      0.upto(5){|m|
        output =   @list[n][m] == R ? 'R' :
                   @list[n][m] == Y ? 'Y' :
                   @list[n][m] == G ? 'G' : ' '
        print(output)
      }
      print "\n"
    }
    p '-------------------------'
  end

end

puyo_list = Array.new

puyo_list << [G,R,Y,G,Y,R]
puyo_list << [G,R,Y,G,Y,R]
puyo_list << [G,R,Y,G,Y,R]
puyo_list << [R,Y,G,Y,G,G]
puyo_list << [Y,R,R,G,R,G]
puyo_list << [Y,G,Y,R,Y,R]
puyo_list << [Y,G,Y,R,Y,R]
puyo_list << [G,Y,R,Y,R,G]
puyo_list << [Y,G,Y,R,Y,G]
puyo_list << [R,Y,G,Y,R,G]
puyo_list << [G,Y,G,Y,R,R]
puyo_list << [R,Y,Y,G,Y,G]
puyo_list << [N,N,G,Y,R,R]

puyo = PuyoPuyo.new puyo_list
puyo.delete