# rule30.py
# Copyright (C) 2002  Frank Buß (fb@frank-buss.de)
# Thanks to Carl Banks, Sean Richards and others for the optimisation tips
# Uses Numeric for fast automaton calculation

from Numeric import *

# This class calculates one line with of Rule 30:
# If the cell and its righthand neighbour were white on
# the previous step, then take the new colour to be whatever
# the previous colour of its lefthand neighbour was, otherwise take 
# the new colour to be the opposite of that 
class Rule30:
  def __init__(self, length):
    # create arrays
    self.current = zeros(length, Int)
    self.workspace = zeros(length - 2, Int)
    
    # create slices
    self.left = self.current[:-2]
    self.right = self.current[2:]
  
  def step(self):
    # calculate the new values using bitwise operators
    self.workspace[:] = self.left ^ (self.current[1:-1] | self.right)

    # update current
    self.current[1:-1] = self.workspace

# create the Rule 30 object and init the middle to 1
length = 10000
rule30 = Rule30(length)
rule30.current[length / 2] = 1

# print the number of '1's for all automaton steps
for step in range(length / 2):
  print sum(rule30.current) 
  rule30.step()
