require 'CSLSystem' describe "LSystem" do context "given axiom 'baaaaaa'" do context "with function b=a" do describe "#generate" do it "should equal 'baaaaaa' at zero iteration" do LSystem.new('baaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(0).should == 'baaaaaa' end it "should equal 'abaaaaa' after one iteration" do LSystem.new('baaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(1).should == 'abaaaaa' end it "should equal 'aabaaaa' after one iteration" do LSystem.new('abaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(1).should == 'aabaaaa' end it "should equal 'aabaaaa' after two iterations" do LSystem.new('baaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(2).should == 'aabaaaa' end it "should equal 'aaabaaa' after three iteration" do LSystem.new('baaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(3).should == 'aaabaaa' end it "should equal 'aaaaaba' after five iteration" do LSystem.new('baaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(5).should == 'aaaaaba' end it "should equal 'baaaaaa' after seven iterations" do LSystem.new('baaaaaa', {'b' => 'a', 'b<a' => 'b'}).generate(7).should == 'baaaaaa' end end end end end
Here is some code designed to pass the rspec tests:-
###################################### # cs_grammar.rb a context sensitive # 1-L lsystem grammar for # ruby/ruby-processing # by Martin Prout (January 2013) ###################################### ################################## # The grammar class stores rules # in two Hashes, one for cs rules, # one for context free rules. Rules # are filtered on input, and context # is checked using get_rule in production ################################## class LSystem attr_reader :axiom, :context, :no_context, :idx def initialize(axiom, rules) @axiom = axiom @no_context = {} @context = {} rules.each_pair do |pair| add_rule pair[0], pair[1] end end def add_rule(pre, rule) if pre.length == 3 if pre[1] == '<' @context[pre[2]] = pre elsif pre[1] == '>' @context[pre[0]] = pre if pre[1] == '>' end @no_context[pre] = rule # key length == 3 elsif pre.length == 1 @no_context[pre] = rule # key length == 1 else print "unrecognized grammar '#{pre}'" end end def generate(repeat = 0) # repeat iteration grammar rules prod = axiom repeat.times do prod = new_production(prod) end return prod end def new_production prod # single iteration grammar rules @idx = 0 prod.gsub!(/./) do |ch| get_rule(prod, ch) end end def get_rule prod, ch rule = ch # default is return original character as rule (no change) @idx += 1 # increment the index of axiom/production as a side effect if (context.has_key?(ch)) if context[ch][1] == "<" cs_char = context[ch][0] rule = no_context[context[ch]] if cs_char == prod[idx - 2] # use context sensitive rule elsif context[ch][1] == ">" cs_char = context[ch][2] rule = no_context[context[ch]] if cs_char == prod[idx] # use context sensitive rule end else rule = no_context[ch] if no_context.has_key?(ch) # context free rule if it exists end return rule end end
Result
.......
Finished in 0.00261 seconds 7 examples, 0 failures
Some more tests...
require 'CSLSystem' describe "LSystem" do context "given axiom 'aaaaaaab'" do context "with function b=a" do describe "#generate" do it "should equal 'aaaaaaab' at zero iteration" do LSystem.new('aaaaaaab', {'b' => 'a', 'a>b' => 'b'}).generate(0).should == 'aaaaaaab' end it "should equal 'aaaaaba' after one iteration" do LSystem.new('aaaaaaab', {'b' => 'a', 'a>b' => 'b'}).generate(1).should == 'aaaaaaba' end it "should equal 'aaaabaa' after one iteration" do LSystem.new('aaaaaaba', {'b' => 'a', 'a>b' => 'b'}).generate(1).should == 'aaaaabaa' end it "should equal ''aaaabaa'' after two iterations" do LSystem.new('aaaaaaab', {'b' => 'a', 'a>b' => 'b'}).generate(2).should == 'aaaaabaa' end it "should equal 'aaabaaa' after three iteration" do LSystem.new('aaaaaaab', {'b' => 'a', 'a>b' => 'b'}).generate(3).should == 'aaaabaaa' end it "should equal 'abaaaaa' after five iteration" do LSystem.new('aaaaaaab', {'b' => 'a', 'a>b' => 'b'}).generate(5).should == 'aabaaaaa' end it "should equal 'aaaaaaab' after seven iterations" do LSystem.new('aaaaaaaa', {'b' => 'a', 'a>b' => 'b'}).generate(7).should == 'aaaaaaaa' end end end end end
Here is the revised code to pass both sets of test...
###################################### # cs_grammar.rb a context sensitive # 1-L lsystem grammar for # ruby/ruby-processing # by Martin Prout (January 2013) ###################################### ################################## # The grammar class stores rules # in two Hashes, one for cs rules, # one for context free rules. Rules # are filtered on input, and context # is checked using get_rule in production ################################## class LSystem attr_reader :axiom, :context, :no_context, :idx def initialize(axiom, rules) @axiom = axiom @no_context = {} @context = {} rules.each_pair do |pair| add_rule pair[0], pair[1] end end def add_rule(pre, rule) if pre.length == 3 if pre[1] == '<' @context[pre[2]] = pre elsif pre[1] == '>' @context[pre[0]] = pre end @no_context[pre] = rule # key length == 3 elsif pre.length == 1 @no_context[pre] = rule # key length == 1 else print "unrecognized grammar '#{pre}'" end end def generate(repeat = 0) # repeat iteration grammar rules prod = axiom repeat.times do prod = new_production(prod) end return prod end def new_production prod # single iteration grammar rules @idx = -1 prod.gsub!(/./) do |ch| get_rule(prod, ch) end end def get_rule prod, ch rule = ch # default is return original character as rule (no change) @idx += 1 # increment the index of axiom/production as a side effect if (context.has_key?(ch)) if context[ch][1] == '<' cs_char = context[ch][0] rule = no_context[context[ch]] if cs_char == prod[idx - 1] # use context sensitive rule elsif context[ch][1] == '>' cs_char = context[ch][2] rule = no_context[context[ch]] if cs_char == prod[idx + 1] # use context sensitive rule end else rule = no_context[ch] if no_context.has_key?(ch) # context free rule if it exists end return rule end end
No comments:
Post a Comment