> 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.

Well, I ended up cleaning up my submission a bit anyway. I still have
another approach in mind, but making a few changes to get this was
pretty easy.  Now, I basically encode only one kind of fold
(top-to-bottom), and turn the paper a few times before and after the
fold to get the desired results.

I think I saw another approach do something very similar if not the
same, but I swear I didn't cheat!  =)


class Integer
   def pow2?
      (self & (self-1)).zero? and not self.zero?
   end

   def even?
      (self & 1).zero?
   end
end


class Array
   def reflect    # vertical
      self.reverse
   end

   def turn       # 90 deg CCW
      self.transpose.reflect
   end

   def fold       # top to bottom
      raise "Invalid fold." unless size.even?
      w, hh = self[0].size, size / 2
      above, below = self[0, hh].reverse, self[hh, hh]
      Array.build_2d(w,hh) { |r,c| above[r][c].reverse.concat below[r][c] }
   end

   def Array.build_2d(w, h)
      Array.new(h) do |r|
         Array.new(w) do |c|
            yield r, c
         end
      end
   end
end


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

   def fold!(cmds)
      cmds.each_byte do |cmd|
         case cmd
         when ?T
            @rows = @rows.fold
         when ?B
            @rows = @rows.turn.turn.fold.turn.turn
         when ?L
            @rows = @rows.turn.turn.turn.fold.turn
         when ?R
            @rows = @rows.turn.fold.turn.turn.turn
         end
      end
      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)
end