On Fri, 25 May 2007 22:18:32 +0900, Ruby Quiz wrote:

> The three rules of Ruby Quiz:
> 
> 1.  Please do not post any solutions or spoiler discussion for this quiz
> until 48 hours have passed from the time on this message.
> 
> 2.  Support Ruby Quiz by submitting ideas as often as you can:
> 
> http://www.rubyquiz.com/
> 
> 3.  Enjoy!
> 
> Suggestion:  A [QUIZ] in the subject of emails about the problem helps
> everyone on Ruby Talk follow the discussion.  Please reply to the
> original quiz message, if you can.
> 
> -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
=-=-=-=-=
> 
> by Drew Olson
> 
> When I learned about fractals in high school math class, I immediately
> found them fascinating. For those of you unfamiliar with the concept,
> the definition from Wikipedia is as follows: a fractal is "a rough or
> fragmented geometric shape that can be subdivided in parts, each of
> which is (at least approximately) a reduced-size copy of the whole".
> 
> At the end of the unit in which we were taught them, the fractal below
> was a test question. In subsequent years, I began drawing it freehand to
> higher and higher levels. The details and patterns that emerge are
> fascinating.
> 
> The goal is to create a ruby program which takes the level as an
> argument and then draws the fractal shown below to the specified level.
> The fractal is created by drawing the first level, then repeating the
> pattern such that each base piece is replaced with the fractal from the
> higher level. Thus, to move from level 1 to level 2, we replace each
> line with the shape at level 1. Notice that the position changes as
> well, meaning if the line is vertical we replace it with a vertically
> positioned shape of level 1 (right and left facing also matter). I have
> shown the first 3 levels below (including the base component at level
> 0). Feel free to use the console for output or get fancy with RMagick or
> something similar.
> 
> 	                          _                  <-- Level 0
> 	                          _
> 	                        _| |_                <-- Level 1
> 	                          _
> 	                        _| |_
> 	                      _|     |_              <-- Level 2
> 	                    _|_       _|_
> 	                  _| |_|     |_| |_
> 	
> 	                          _
> 	                        _| |_
> 	                      _|     |_
> 	                    _|_       _|_
> 	                  _| |_|     |_| |_
> 	                _|                 |_
> 	              _|_                   _|_
> 	            _| |_|                 |_| |_    <-- Level 3
> 	          _|                             |_
> 	        _|_                               _|_
> 	      _| |_|_   _                   _   _|_| |_
> 	    _|     |_|_|_|                 |_|_|_|     |_
> 	  _|_       _|_|_                   _|_|_       _|_
> 	_| |_|     |_| |_|                 |_| |_|     |_| |_

#this is my second solution. it builds on my first solution
#but reimplements the turtle graphics in ASCII art.
class Fractal
   #rotate the turtle 90 degrees to the :left or the :right
   def rotate whichway
      #lots of special cases to deal with the nature of the
      #characters used.
      case [@direction,whichway]
      when [:left,:left],[:right,:right]
	 @y+=1
	 @direction=:down
      when [:right,:left],[:left,:right]
	 @direction=:up
      when [:down,:right]
	 @x-=1
	 @y-=1
	 @direction=:left
      when [:up,:left]
	 @x-=1
	 @direction=:left
      when [:up,:right]
	 @x+=1
	 @direction=:right
      when [:down,:left]
	 @x+=1
	 @y-=1
	 @direction=:right
      end
      self
   end

   #creates a blank canvas of the specified size, with the turtle in the 
   #lower left corner, facing right
   def initialize width=80,height=24
      @x=0
      @y=height-1
      @direction=:right
      @matrix=Array.new(height){Array.new(width){" "}}
   end

   #move the turtle forward
   def forward
      case @direction
      when :left
	 @matrix[@y][@x]="_"
	 @x-=1
      when :right
	 @matrix[@y][@x]="_"
	 @x+=1
      when :up
	 @matrix[@y][@x]="|"
	 @y-=1
      when :down
	 @matrix[@y][@x]="|"
	 @y+=1
      end
      self
   end

   #draw a segment of the fractal
   def segment depth
      if depth==0
	 forward
      else
	 segment depth-1
	 rotate :left
	 segment depth-1
	 rotate :right
	 segment depth-1
	 rotate :right
	 segment depth-1
	 rotate :left
	 segment depth-1
      end
      self
   end

   #convert the matrix to a string suitable for printing
   def to_s
      @matrix.map{|row| row.join}.join("\n")
   end
end

puts Fractal.new.segment(3)


-- 
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/