[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Fwd: [QUIZ] Grid Folding (#63

James Gray

1/22/2006 6:21:00 PM


7 Answers

matthew.moss.coder

1/22/2006 10:12:00 PM

0

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


matthew.moss.coder

1/23/2006 4:14:00 PM

0

> 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


matthew.moss.coder

1/23/2006 4:15:00 PM

0

Just realized I now use my Array.reflect in only one place, and it
only does a reverse, so that should be refactored out.


matthew.moss.coder

1/23/2006 4:18:00 PM

0

Actually .... (and I feel like I'm saying this just for my own
benefit, please forgive my rambling) ... now that I put most
operations into Array, the Paper class is mostly pointless, since I
wanted to change mutating fold! to non-mutating fold (esp considering
its return type), and I might as well then just move the dimension
check, iteration and fold processing into the global fold function
anyway.

Silly me.

On 1/23/06, Matthew Moss <matthew.moss.coder@gmail.com> wrote:
> Just realized I now use my Array.reflect in only one place, and it
> only does a reverse, so that should be refactored out.


matthew.moss.coder

1/23/2006 4:23:00 PM

0

On that note (i.e., that I'm talking to myself), here is the final
3-deep nested array version. I won't touch this again.


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.new_2d(w,hh) { |r,c| above[r][c].reverse.concat below[r][c] }
end

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


def fold(w, h, cmds)
raise "Bad dimensions: #{w}x#{h}" unless w.pow2? and h.pow2?
paper = Array.new_2d(w, h) { |r,c| [w*r + c + 1] }

cmds.each_byte do |cmd|
case cmd
when ?T
paper = paper.fold
when ?R
paper = paper.turn.fold.turn.turn.turn
when ?B
paper = paper.turn.turn.fold.turn.turn
when ?L
paper = paper.turn.turn.turn.fold.turn
end
end

raise "Not enough folds!" unless paper[0][0] == paper.flatten
paper[0][0]
end


Levin Alexander

1/23/2006 4:38:00 PM

0

On 1/23/06, Matthew Moss <matthew.moss.coder@gmail.com> wrote:> paper = Array.new_2d(w, h) { |r,c| [w*r + c + 1] }require 'enumerator'paper = (1..w*h).to_enum(:each_slice, w).to_aLevin, :)

Paul Novak

1/24/2006 3:00:00 AM

0