Here is my own solution, using 3-deep nested arrays. I could clean
this up a bit more, I think, but I am looking at another approach I
want to try before I summarize later this week.


class Integer
   def pow2?
      (self & (self-1)) == 0
   end
end


class Paper
   def build(w, h)
      Array.new(h) do |r|
         Array.new(w) do |c|
            yield r, c
         end
      end
   end

   def initialize(w, h)
      raise "Bad dimensions: #{w}x#{h}" unless w.pow2? and h.pow2?
      @rows = build(w, h) { |r,c| [w*r + c + 1] }
   end

   def rows
      @rows.dup
   end

   def cols
      build(@rows.size, @rows[0].size) { |c,r| @rows[r][c] }
   end

   def v_fold(i)
      rs = rows
      hh = rs.size / 2
      raise "Too many vertical folds." if hh == 0
      above, below = rs[i*hh, hh].reverse, rs[(1-i)*hh, hh]
      build(above[0].size, above.size) do |r, c|
         above[r][c].reverse.concat below[r][c]
      end
   end

   def h_fold(i)
      cs = cols
      hw = cs.size / 2
      raise "Too many horizontal folds." if hw == 0
      above, below = cs[i*hw, hw].reverse, cs[(1-i)*hw, hw]
      build(above.size, above[0].size) do |c, r|
         above[r][c].reverse.concat below[r][c]
      end
   end

   def fold!(cmds)
      cmds.each_byte do |cmd|
         case cmd
         when ?T
            @rows = v_fold(0)
         when ?B
            @rows = v_fold(1)
         when ?L
            @rows = h_fold(0)
         when ?R
            @rows = h_fold(1)
         end
      end
      self
   end

    def result
      raise "Not enough folds!" unless @rows[0][0] == @rows.flatten
      @rows[0][0]
   end
end


def fold(w, h, cmds)
   Paper.new(w, h).fold!(cmds).result
end