Mercurial > public > think_complexity
view ch6ex2_4.py @ 42:039249efe42f
Chapter 6, exercise 2, #4. Wrote a program to output the center column of
a rule 30 CA as a stream of bytes. It is very slow though. It has to run a very
long time to produce enough data for dieharder. Committing it now but will have
to let it run overnight or something to generate a large file.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sun, 13 Jan 2013 16:24:00 -0600 |
parents | |
children |
line wrap: on
line source
"""Chapter 6, exercise 2 in Allen Downey's Think Complexity book. 4. Implement a Rule 30 CA on a ring with a few hundred cells, run it for as many time steps as you can in a reasonable amount of time, and output the center column as a sequence of bits. Test it using DieHarder. We'll take a slightly different tact. We will create a program that will continually output the center column as a bit stream. Once we reach the end of the time steps, we'll copy the last row to row 0 and start again. This way we can feed the data into dieharder over a pipe without it exhausting our stream. """ import sys from CircularCA import CircularCA def main(script, bytes_wanted): bytes_wanted = int(bytes_wanted) # Create a circular CA that is 257 columns; it is odd so that we have a true # "center" column. Our CA will have 8192 steps. This will give us 8192 # / 8 == 1024 bytes of pseudo-random (we hope) data using rule 30. Once # we've reached the end of the time steps, we'll copy the last row to the # first and start over. rows = 8193 cols = 257 mid = cols // 2 ca = CircularCA(30, rows, cols) ca.start_single() iters = 0 bytes_produced = 0 while True: ca.loop(rows - 1) iters += 1 if iters == 1: # don't use the first iteration as the first few rows will have 0's # until it fills up ca.wrap() continue a = ca.get_array(mid, mid + 1) # output the bit stream a byte at a time x = 0 i = 0 for n, item in enumerate(a): # don't use the first bit because it is a repeat from the previous # iteration if n == 0: continue x <<= 1 x |= item[0] i += 1 if i == 8: sys.stdout.write(chr(x)) x = 0 i = 0 bytes_produced += 1 if bytes_produced >= bytes_wanted: return # we're done # now start the CA over: ca.wrap() if __name__ == '__main__': main(*sys.argv)