Account Options

  1. Sign in
The old Google Groups will be going away soon, but your browser is incompatible with the new version.
Google Groups Home
« Groups Home
Message from discussion #63: Grid Folding

Path: g2news1.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!nx02.iad01.newshosting.com!newshosting.com!newsfeed.icl.net!newsfeed.fjserv.net!newsfeed.arcor.de!noris.net!not-for-mail
From: "Dominik Bathon" <dba...@gmx.de>
Newsgroups: comp.lang.ruby
Subject: Re: [/QUIZ] #63: Grid Folding
Date: Wed, 25 Jan 2006 06:56:07 +0900
Lines: 89
Message-ID: <op.s3wkj6hvd62ajc@localhost>
References: <43D38F5C.3000706@blanshard.us>
NNTP-Posting-Host: sinus.lauschmusik.de
Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
Content-Transfer-Encoding: quoted-printable
X-Trace: ork-un.noris.net 1138139825 29549 213.95.32.201 (24 Jan 2006 21:57:05 GMT)
X-Complaints-To: news@noris.net
NNTP-Posting-Date: Tue, 24 Jan 2006 21:57:05 +0000 (UTC)
X-received-from: This message has been automatically forwarded from
   the ruby-talk mailing list by a gateway at lauschmusik.de. If it is
   SPAM, it did not originate at lauschmusik.de. Please report the 
   original sender, and not us. Thanks!
   Please see http://hypermetrics.com/rubyhacker/clrFAQ.html#tag24 to.
In-Reply-To: <43D38F5C.3000706@blanshard.us>
X-ML-Name: ruby-talk
X-Mail-Count: 176829
X-ruby-talk: <op.s3wkj6hvd62ajc@localhost>
X-rubymirror: yes

Here is mine.

It supports square grids of all size, the size is "autodetected" from the=
 =20
length of the fold string.

Dominik


# A simple 2D array, the width and height are immutable once it is create=
d.
class Array2D
     attr_reader :w, :h
     def initialize(w, h, init_array =3D nil)
         @w, @h=3Dw, h
         @array =3D init_array || []
     end
     def [](x, y)
         @array[(y%h)*w+(x%w)]
     end
     def []=3D(x, y, v)
         @array[(y%h)*w+(x%w)]=3Dv
     end
end

class GridFold
     attr_reader :grid

     # the initial grid will be (2**n)x(2**n)
     def initialize(n =3D 4)
         d =3D 1 << n
         @grid =3D Array2D.new(d, d, (1..(d*d)).map { |i| [i] })
     end

     def fold_t
         fold_help(@grid.w, @grid.h / 2) { |x, y, _, nh|
             @grid[x, nh-1-y].reverse + @grid[x, nh+y]
         }
     end
     def fold_b
         fold_help(@grid.w, @grid.h / 2) { |x, y, _, _|
             @grid[x, @grid.h-1-y].reverse + @grid[x, y]
         }
     end
     def fold_l
         fold_help(@grid.w / 2, @grid.h) { |x, y, nw, _|
             @grid[nw-1-x, y].reverse + @grid[nw+x, y]
         }
     end
     def fold_r
         fold_help(@grid.w / 2, @grid.h) { |x, y, _, _|
             @grid[@grid.w-1-x, y].reverse + @grid[x, y]
         }
     end

     def self.fold(folds_str)
         folds =3D folds_str.to_s.downcase
         n =3D folds.size / 2
         unless folds =3D~ /\A[tblr]*\z/ && folds.size =3D=3D n * 2
             raise "invalid argument"
         end
         gf =3D self.new(n)
         folds.scan(/./) { |f| gf.send("fold_#{f}") }
         gf.grid[0, 0]
     end

     private

     def fold_help(new_width, new_height)
         raise "impossible" unless new_width >=3D 1 && new_height >=3D 1
         new_grid =3D Array2D.new(new_width, new_height)
         new_width.times { |x| new_height.times { |y|
             new_grid[x, y] =3D yield x, y, new_width, new_height
         } }
         @grid =3D new_grid
         self
     end
end

if $0 =3D=3D __FILE__
     begin
         p GridFold.fold(ARGV.shift.to_s)
     rescue =3D> e
         warn e
         exit 1
     end
end