My solution.
#! /usr/bin/env ruby
def fold row_siz, cmds
# paper is an array of layers,
# each layer is an array of rows,
# each row is an array of integers
paper = []
layer = []
1.upto(row_siz){|i|
row = []
1.upto(row_siz){|j| row << j + row_siz*(i-1)}
layer << row
}
paper = [ layer ]
nfold = (Math.log(row_siz)/Math.log(2)) # Number of folds each direction
# validate inputs
raise "Array size not a power of 2" unless 2**nfold == row_siz
raise "Invalid cmd length" unless cmds.length == nfold * 2
raise "Invalid fold chars" unless cmds.scan(/[TBLR]/).length == nfold * 2
raise "Invalid fold list" unless cmds.scan(/[TB]/).length == nfold
cmds.split(//).each{|f|
new_paper = []
case f
when 'L','R'
row_siz = paper[0][0].length/2
s1, s2 = (f == 'L') ? [0,row_siz] : [row_siz,0]
paper.reverse.each { |layer|
new_layer = []
layer.each {|row|
new_layer << row.slice(s1,row_siz).reverse
}
new_paper << new_layer
}
paper.each { |layer|
new_layer = []
layer.each {|row|
new_layer << row.slice(s2,row_siz)
}
new_paper << new_layer
}
when 'T','B'
col_siz = paper[0].length/2
s1, s2 = (f == 'T') ? [0,col_siz] : [col_siz,0]
paper.reverse.each { |layer|
new_paper << layer.slice(s1,col_siz).reverse
}
paper.each { |layer|
new_paper << layer.slice(s2, col_siz)
}
end
paper = new_paper
}
return paper.flatten
end
def usage
puts "Usage #{File.basename($0)} <grid sz> <fold list>"
puts " grid sz must be power of 2"
puts " valid fold are T, B, R, L"
puts " you must have enough folds to get NxN to 1x1"
exit
end
usage unless ARGV.length == 2
row_siz = ARGV[0].to_i
cmds = ARGV[1]
res = fold(row_siz, cmds)
puts "RES"
puts "[ #{res.join(', ')} ]"