--Boundary-00dwvGh1C3FtoFsb
Content-Type: Multipart/Mixed;
  boundaryoundary-00dwvGh1C3FtoFsb"

--Boundary-00dwvGh1C3FtoFsb
Content-Type: text/plain;
  charsettf-8"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

Here's my fairly straightforward, no bells-and-whistles solution.

Each state is represented as an Array of Strings. I originally just used
a String, and split() when needed, but keeping it as an Array makes it a
bit faster and does simplify the code in a few places.

transformer() builds a Proc that takes a neighborhood as its argument (as
an Array of Strings) and returns the transformed cell state (as a String).
A Hash could have been used instead of a Proc.

step() takes a state (as an Array of Strings), tacks [0,0] onto both ends,
and calls each_cons(3) to iterate through the neighborhoods, which are
passed to the transformer Proc.

$ ./cellular_automata.rb -r 110 -s 1 -n 15
               X
              XX
             XXX
            XX X
           XXXXX
          XX   X
         XXX  XX
        XX X XXX
       XXXXXXX X
      XX     XXX
     XXX    XX X
    XX X   XXXXX
   XXXXX  XX   X
  XX   X XXX  XX
 XXX  XXXX X XXX
XX X XX  XXXXX X

-- 
Jesse Merriman
jessemerriman / warpmail.net
http://www.jessemerriman.com/

--Boundary-00dwvGh1C3FtoFsb
Content-Type: application/x-ruby;
  name
ellular_automata.rb" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename
ellular_automata.rb" #!/usr/bin/env ruby # Ruby Quiz 134: Cellular Automata require 'enumerator' require 'getoptlong' Draw :blank ' ', '0' ' ', '1' 'X' } Edge 0, 0] NeighborhoodSize # Build a Proc that takes a neighborhood as its argument and returns the # transformed cell state. def transformer rule_num rule ule_num.to_s 2 rule '0' * (2**NeighborhoodSize - rule.length) + rule).reverse.split(//) lambda { |hood| rule[hood.join.to_i(2)] } end # Takes the current state and a transformation Proc, and returns the next # state. def step state, trans new_state ] (Edge + state + Edge).each_cons(NeighborhoodSize) do |hood| new_state << trans[hood] end new_state end # Outputs the current state. The current step number and total step number are # needed to calculate how far to indent. def puts_state state, step, total_steps puts Draw[:blank] * (total_steps - step) + state.map { |x| Draw[x] }.join end if __FILE__ $0 Opts etoptLong.new( [ '--rule', '-r', GetoptLong::REQUIRED_ARGUMENT ], [ '--state', '-s', GetoptLong::REQUIRED_ARGUMENT ], [ '--steps', '-n', GetoptLong::REQUIRED_ARGUMENT ] ) # defaults rule 10 state w{ 1 } steps 0 Opts.each do |opt, arg| case opt when '--rule'; rule rg.to_i when '--state'; state rg.split(//) when '--steps'; steps rg.to_i end end trans ransformer(rule) puts_state state, 0, steps steps.times do |s| state tep(state, trans) puts_state state, s+1, steps end end --Boundary-00dwvGh1C3FtoFsb-- --Boundary-00dwvGh1C3FtoFsb--