Guest User

Untitled

a guest
Nov 23rd, 2017
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 4.66 KB | None | 0 0
  1. require 'csv'
  2.  
  3. # パネルクイズ全体
  4. class Problem
  5.   attr_accessor :lx, :rx, :ux, :dx, :n
  6.   attr_accessor :boardList
  7. end
  8.  
  9. # パネルクイズの「ボード」
  10. class Board
  11.  
  12.   attr_accessor :w, :h # 幅、高さ
  13.   attr_accessor :b, :e # ボードの現在状態、終了時の状態(char[])
  14.   attr_accessor :uf, :lf # 埋まっている行数(上部)、列数(左部)
  15.  
  16.   @@asc = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("")
  17.  
  18.   def initialize(w,h,b)
  19.     @w = w; @h = h; @b = b.clone(); @uf = 0; @lf = 0
  20.   end
  21.  
  22.   # 終了時の状態
  23.   def endStatus()
  24.     return @e if @e != nil
  25.     buff = b.clone.sort()
  26.     buff.delete("0")
  27.     size = buff.size() - 1
  28.     buff.delete("=")
  29.     for i in 0..size
  30.       buff[i,0] = "=" if buff[i] != @@asc[i]
  31.     end
  32.     buff << "0"
  33.     @e = buff
  34.   end
  35.  
  36.   # 左右上下の各方向について、0パネルが移動可能かどうかの判定
  37.   def movable?()
  38.     pos = b.index("0")
  39.     l = (pos % w > lf)     && b[pos-1] != '=' # lf対策済み
  40.     r = (pos % w != (w-1)) && b[pos+1] != '='
  41.     u = (pos >= w*(1+uf))  && b[pos-w] != '=' # uf対策済み
  42.     d = (b[pos+w] != nil)  && b[pos+w] != '='
  43.     return [l, r, u, d]
  44.   end
  45.  
  46.   # 0パネルをdirの方向に移動する
  47.   def move(dir)
  48.     pos    = b.index("0").to_i
  49.     # p "pos:#{pos} dir:#{dir} w:#{w}"
  50.     moveTo = { "l" => pos-1, "r" => pos+1, "u" => pos-w, "d" => pos+w }[dir]
  51.     # tPos    = endStatus.index(b[pos])
  52.     # tMoveTo = endStatus.index(b[moveTo])
  53.     # p "pos=#{pos}, moveTo=#{moveTo}, " #tPos=#{tPos}, tMoveTo=#{tMoveTo}"
  54.     swap(pos, moveTo)
  55.     # p "score=#{score}"
  56.     # p ["move::",diff(pos,tPos), diff(moveTo,tMoveTo), diff(moveTo,tPos), diff(pos,tMoveTo)]
  57.     # score = score() # - diff(pos,tPos) - diff(moveTo,tMoveTo) + diff(moveTo,tPos) + diff(pos,tMoveTo)
  58.     return self
  59.   end
  60.  
  61.   # 新たに上部・左部が埋まったかどうかの判定
  62.   def check ()
  63.     # check_w
  64.     w_filled = true
  65.     for i in 0..(@h-1)
  66.       pos = w * (i) + lf
  67.       w_filled = false if ( b[pos] != "=" && b[pos] != @@asc[pos] )
  68.     end
  69.     #check_w
  70.     h_filled = true
  71.     for j in 0..(@w-1)
  72.       pos = w * uf + j
  73.       h_filled = false if ( b[pos] != "=" && b[pos] != @@asc[pos] )
  74.     end
  75.     return w_filled, h_filled
  76.   end
  77.  
  78.   def swap(i,j)
  79.     tmp = b[i]
  80.     b[i] = b[j]
  81.     b[j] = tmp
  82.   end
  83.  
  84.   def print
  85.     (0..(h-1)).any? {|i| p b[(i*w)..((i+1)*w-1)] }
  86.   end
  87.  
  88. end
  89.  
  90. # ボードの局面
  91. class State
  92.  
  93.   attr_accessor :key, :minPath #連想配列格納用のキー(ボード状態の文字列)、この局面に至る最小パス
  94.   attr_accessor :board
  95.  
  96.   def initialize(board,minPath)
  97.     @key       = board.b.join()
  98.     @board     = board
  99.     @minPath   = minPath
  100.   end
  101.  
  102.   # dir方向に移動し、次の局面へ
  103.   def move(dir)
  104.     return State.new( Board.new(@board.w,@board.h,@board.b).move(dir), @minPath + dir )
  105.   end
  106.  
  107.   # 終了判定
  108.   def isEnd?
  109.     return @board.b == @board.endStatus()
  110.   end
  111.  
  112.   # どの程度埋まっているか?(高いほど、優先的に処理する)
  113.   def lv?
  114.     return board.lf + board.uf
  115.   end
  116.  
  117.   def printState(message)
  118.     l, r, u, d = board.movable?()
  119.     print "------------------------------------------------\n"
  120.     print "-- #{message}\n"
  121.     print  "## path     ## [#{minPath}]\n"
  122.     print  "## movable? ## l=#{l},r=#{r},u=#{u},d=#{d}\n"
  123.     board.print()
  124.   end
  125. end
  126.  
  127. # 局面の重み付きキュー(lvが高いほど優先)
  128. class StateQueue
  129.  
  130.   def initialize(n)
  131.     @queues = Array.new
  132.     for i in 0..n
  133.       @queues[i] = Array.new
  134.     end
  135.   end
  136.  
  137.   def enqueue(state)
  138.     lv = state.lv?
  139.     @queues[lv] << state
  140.   end
  141.  
  142.   def dequeue()
  143.     for i in 1..@queues.size
  144.       lv = @queues.size - i
  145.       if @queues[lv]!=nil && @queues[lv].size > 0
  146.         return @queues[lv].shift()
  147.       end
  148.     end
  149.     p "nil"
  150.     return nil
  151.   end
  152.  
  153.   def size()
  154.     size = 0
  155.     for i in 0..@queues.size-1
  156.       size = size + @queues[i].size() if @queues[i] != nil
  157.     end
  158.     return size
  159.   end
  160.  
  161.   def to_s()
  162.     a = Array.new
  163.     for i in 0..@queues.size-1
  164.       a[i] = @queues[i].size()
  165.     end
  166.     return "[#{a.join(',')}]"
  167.   end
  168.  
  169. end
  170.  
  171. # 問題をCSVファイルから読む人
  172. class ProblemReader
  173.   def load(file)
  174.     problem = Problem.new
  175.     problem.boardList = Array.new
  176.     i = 0
  177.     CSV.open( file, 'r') do |row|
  178.       case i
  179.       when 0 then
  180.         problem.lx, problem.rx, problem.ux, problem.dx = row[0].split(' ')
  181.       when 1 then
  182.         problem.n = row
  183.       else
  184.         board = Board.new(row[0].to_i, row[1].to_i, row[2].split(""))
  185.         problem.boardList << board
  186.       end
  187.       i = i + 1
  188.     end
  189.     return problem
  190.   end
  191. end
Add Comment
Please, Sign In to add comment