bgneal@45: """Chapter 6, exercise 4 in Allen Downey's Think Complexity book. bgneal@45: bgneal@45: The goal of this exercise is to implement a Turing machine. bgneal@45: See http://en.wikipedia.org/wiki/Turing_machine. bgneal@45: bgneal@45: 4. Write a class named TMDrawer that generates an image that represents the bgneal@45: state of the tape and the position and state of the head. For one example of bgneal@45: what that might look like, see bgneal@45: http://mathworld.wolfram.com/TuringMachine.html. bgneal@45: bgneal@45: """ bgneal@45: import matplotlib.pyplot as pyplot bgneal@45: import numpy bgneal@45: bgneal@45: from CADrawer import Drawer bgneal@45: bgneal@45: bgneal@45: class TMDrawer(Drawer): bgneal@45: """Implementation of Drawer using matplotlib for Turing Machines. bgneal@45: bgneal@45: We visualize the tape and machine head/state by drawing the tape state as bgneal@45: a row, then adding a row underneath that for the head & state. The tape head bgneal@45: is drawn as a solid square whose color represents the state. bgneal@45: bgneal@45: """ bgneal@45: def __init__(self, tape_colors, state_colors, cmap=None): bgneal@45: self.tape_colors = tape_colors bgneal@45: self.state_colors = state_colors bgneal@45: self.cmap = cmap if cmap else 'spectral' bgneal@45: bgneal@45: def draw(self, tm, start=0, end=None): bgneal@45: """Draws the TM using pyplot.pcolor.""" bgneal@45: tape = tm.get_array(start, end) bgneal@45: rows, cols = tape.shape bgneal@45: bgneal@45: # create a new array that has twice as many rows bgneal@45: steps = rows bgneal@45: rows *= 2 bgneal@45: a = numpy.zeros((rows, cols), dtype=numpy.int8) bgneal@45: bgneal@45: # copy the tape state into the array at every other row bgneal@45: for i in xrange(steps): bgneal@45: for j in xrange(cols): bgneal@45: #a[n, j] = self.tape_colors[tape[i, j]] bgneal@45: c = self.tape_colors[tape[i, j]] bgneal@45: a[i * 2, j] = c bgneal@45: bgneal@45: # copy the head position & state into every other row bgneal@45: n = 1 bgneal@45: for pos, state in tm.history: bgneal@45: a[n, pos] = self.state_colors[state] bgneal@45: n += 2 bgneal@45: bgneal@45: # flipud puts the first row at the top; bgneal@45: pyplot.pcolor(numpy.flipud(a), cmap=self.cmap) bgneal@45: pyplot.axis([0, cols, 0, rows]) bgneal@45: pyplot.colorbar() bgneal@45: bgneal@45: # empty lists draw no ticks bgneal@45: pyplot.xticks([]) bgneal@45: pyplot.yticks([]) bgneal@45: bgneal@45: def show(self): bgneal@45: """display the pseudocolor representation of the CA""" bgneal@45: pyplot.show() bgneal@45: bgneal@45: def save(self, filename='tm.png'): bgneal@45: """save the pseudocolor representation of the TM in (filename).""" bgneal@45: pyplot.savefig(filename) bgneal@45: