Mercurial > public > think_complexity
view ch6ex3.py @ 44:362d4ec7e794
Got a first draft Turing Machine working for chapter 6,
exercise 4. Next I have to figure out how to draw it
with a TMDrawer class.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Wed, 16 Jan 2013 21:44:02 -0600 |
parents | 6cd37534c12e |
children |
line wrap: on
line source
"""Chapter 6, exercise 3 in Allen Downey's Think Complexity book. This exercise asks you to experiment with Rule 110 and see how many spaceships you can find. 1. Modify your program from the previous exercises so it starts with an initial condition that yields the stable background pattern. 2. Modify the initial condition by adding different patterns in the center of the row and see which ones yield spaceships. You might want to enumerate all possible patterns of n bits, for some reasonable value of n. For each spaceship, can you find the period and rate of translation? What is the biggest spaceship you can find? """ import os.path import cPickle from CircularCA import CircularCA from CADrawer import PyplotDrawer FILENAME = 'rule110.pkl' RULE = 110 def find_ic(show=False): """This function sets up a rule 110 CA with a random initial condition and runs it for 600 time steps. The last row is the initial condition (IC) we are interested in for producing future CA to investigate rule 110 and spaceships. We use 600 steps because of figure 6.6 in Think Complexity. The CA is run through 600 steps and then the last row is pickled in a file for future use. """ ca = CircularCA(RULE, 600, 600) ca.start_random() ca.loop(599) if show: drawer = PyplotDrawer() drawer.draw(ca) drawer.show() # get the last row of the CA and pickle it to a file so we can use it in the # future: last_row = ca.array[599, :] with open(FILENAME, 'wb') as fp: cPickle.dump(last_row, fp, protocol=2) print "last row pickled in {}".format(FILENAME) def rule110(script, n): """Open the IC pickle file and initialize a CA with it. Modify the 32 center columns with the bit pattern given by n, which should be a hexidecimal number. Then step the CA and display it. """ print 'loading {}...'.format(FILENAME) with open(FILENAME, 'rb') as fp: ic = cPickle.load(fp) print 'creating CA...' ca = CircularCA(RULE, 600, 600) ca.start_row(ic) n = int(n, 16) print 'modifying center of row with {:x}'.format(n) a = ca.array mask = 1 << 31 j = 600 / 2 - 16 + 1 # +1 because of the ghost column on the left for i in xrange(32): a[0, j] = 1 if n & mask else 0 j += 1 mask >>= 1 print 'stepping CA...' ca.loop(599) drawer = PyplotDrawer() drawer.draw(ca) drawer.show() if __name__ == '__main__': import sys if not os.path.exists(FILENAME): find_ic() rule110(*sys.argv)