From: Matthew Moss Date: 2007-05-30T14:05:40+09:00 Subject: Re: [QUIZ] Fractals (#125) Here's my solution... It's the bare minimum of what I wanted to do. I've been wanting to do some L-System type stuff for a while, so I focused a bit on that. There's lots more I want to put into it, like fractional levels, and support for contextual grammars (this is context-free). The design was inspired by Dennis Ranke's second solution to the dice rolling quiz (#61). I had intended to reuse parts of the turtle graphics quiz, but seeing as how I've also got "learn SVG" on my to-do list, I did some quick and dirty SVG output. (Mozilla should be able to open the file.) class LSystem def initialize(&block) @rules = {} instance_eval(&block) end def rule(var) raise "Rule for #{var} must be unique!" if @rules.include?(var.to_sym) @rules[var.to_sym] = yield.map { |x| x.to_sym } end def start(var) @start = var.to_sym end def evaluate(n) product = [@start] n.to_i.times do |i| product.map! do |s| @rules[s.to_sym] || s.to_sym end.flatten! end product.each do |p| send(p) end end end koch = LSystem.new do start :F rule(:F) { %w(F + F - F - F + F) } def F nx, ny = @x + @dx, @y + @dy puts <<-LINE LINE @x, @y = nx, ny end def + @dx, @dy = -@dy, @dx end def - @dx, @dy = @dy, -@dx end def evaluate(n) raise "N must be non-negative" if n < 0 @x, @y = 0, 0 @dx, @dy = 900 / (3 ** n), 0 puts <<-HEADER HEADER super puts <<-FOOTER FOOTER end end koch.evaluate(ARGV[0].to_i)