Python and cellular automata (It works this time!)

Discussion in 'Perl Misc' started by defcon8, Jun 24, 2006.

  1. defcon8

    defcon8 Guest

    I thought people would be interested in this little script I wrote to
    reproduce the 256 simple automata that is shown in the first chapters
    of "A New Kind of Science". You can see a few results without running
    the script, at http://cooper-j.blogspot.com . And here is the code (You
    will need PIL (Python Imaging Library)):
    <code>
    import Image

    # Contract:
    # To simulate simple cellular automata.

    class calculations:
    def __init__(self,which):
    self.against = self.array_maker_2()[which]
    self.check = self.array_maker_1()
    self.array = self.array_maker_3(311)
    self.calculator()

    def binary(self, n, size): ## This is the Int -> str(BINARY)
    converter
    assert n >= 0
    bits = []
    while n:
    bits.append('01'[n&1])
    n >>= 1
    bits.reverse()
    result = ''.join(bits) or '0'
    for iteration in range(len(result),size):
    result = "0" + result
    return result

    def array_maker_1(self): # This makes the array that represents the
    8 different permutations of 3 cells. Itself, its left and its right.
    return [self.binary(n, 3) for n in range(8)]

    def array_maker_2(self): # This makes the array that represents
    every single different rule. If for instance the second element in one
    # of these rules is 1, then the corresponding permutation that may
    be found in the result array (array_maker_3), will be 1 (black).
    return [self.binary(n, 8) for n in range(256)]

    def array_maker_3(self, y): # This is the array for all the
    results. The automaton starts from the middle of the first row
    x = [["0" for x in range((2*y)+1)] for n in range(y)]
    x[0][(2*y+1)/2] = "1"
    return x

    def calculator(self): # This cycles over all of the cells, and
    scans one row at a time, and changes the next row according to the
    current cell.
    self.buff_result = ["0","0","0"] # This is the current permutation
    buffer to be checked against the corresponding arrays.
    for i in range(len(self.array)-1):
    for j in range(1, len(self.array[0])-1):
    self.step1(j,i)
    self.step2(j,i)
    self.step3(j,i)
    y = self.check.index(''.join(self.buff_result))
    self.array[i+1][j] = self.against[y]

    # The steps update the result buffer.
    def step1(self, step, y):
    self.buff_result[0] = self.array[y][step-1]

    def step2(self, step, y):
    self.buff_result[1] = self.array[y][step]

    def step3(self, step, y):
    self.buff_result[2] = self.array[y][step+1]

    for number in range(256):
    objo = calculations(number)
    x = objo.array
    y = []
    for num,zo in enumerate(x):
    for com,wo in enumerate(zo):
    x[num][com] = int(wo)

    nim = Image.new("1", (623,311))

    for n in x: #converting the array of arrays into a single array so
    putdata can take it.
    for p in n:
    y.append(p)
    nim.putdata(y)
    nim.resize((6230/2,3110/2)).save("output" + str(number) + ".png")
    print number
    </code>
     
    defcon8, Jun 24, 2006
    #1
    1. Advertising

  2. defcon8

    placid Guest

    defcon8 wrote:
    > I thought people would be interested in this little script I wrote to
    > reproduce the 256 simple automata that is shown in the first chapters
    > of "A New Kind of Science". You can see a few results without running
    > the script, at http://cooper-j.blogspot.com . And here is the code (You
    > will need PIL (Python Imaging Library)):
    > <code>
    > import Image
    >
    > # Contract:
    > # To simulate simple cellular automata.
    >
    > class calculations:
    > def __init__(self,which):
    > self.against = self.array_maker_2()[which]
    > self.check = self.array_maker_1()
    > self.array = self.array_maker_3(311)
    > self.calculator()
    >
    > def binary(self, n, size): ## This is the Int -> str(BINARY)
    > converter
    > assert n >= 0
    > bits = []
    > while n:
    > bits.append('01'[n&1])
    > n >>= 1
    > bits.reverse()
    > result = ''.join(bits) or '0'
    > for iteration in range(len(result),size):
    > result = "0" + result
    > return result
    >
    > def array_maker_1(self): # This makes the array that represents the
    > 8 different permutations of 3 cells. Itself, its left and its right.
    > return [self.binary(n, 3) for n in range(8)]
    >
    > def array_maker_2(self): # This makes the array that represents
    > every single different rule. If for instance the second element in one
    > # of these rules is 1, then the corresponding permutation that may
    > be found in the result array (array_maker_3), will be 1 (black).
    > return [self.binary(n, 8) for n in range(256)]
    >
    > def array_maker_3(self, y): # This is the array for all the
    > results. The automaton starts from the middle of the first row
    > x = [["0" for x in range((2*y)+1)] for n in range(y)]
    > x[0][(2*y+1)/2] = "1"
    > return x
    >
    > def calculator(self): # This cycles over all of the cells, and
    > scans one row at a time, and changes the next row according to the
    > current cell.
    > self.buff_result = ["0","0","0"] # This is the current permutation
    > buffer to be checked against the corresponding arrays.
    > for i in range(len(self.array)-1):
    > for j in range(1, len(self.array[0])-1):
    > self.step1(j,i)
    > self.step2(j,i)
    > self.step3(j,i)
    > y = self.check.index(''.join(self.buff_result))
    > self.array[i+1][j] = self.against[y]
    >
    > # The steps update the result buffer.
    > def step1(self, step, y):
    > self.buff_result[0] = self.array[y][step-1]
    >
    > def step2(self, step, y):
    > self.buff_result[1] = self.array[y][step]
    >
    > def step3(self, step, y):
    > self.buff_result[2] = self.array[y][step+1]
    >
    > for number in range(256):
    > objo = calculations(number)
    > x = objo.array
    > y = []
    > for num,zo in enumerate(x):
    > for com,wo in enumerate(zo):
    > x[num][com] = int(wo)
    >
    > nim = Image.new("1", (623,311))
    >
    > for n in x: #converting the array of arrays into a single array so
    > putdata can take it.
    > for p in n:
    > y.append(p)
    > nim.putdata(y)
    > nim.resize((6230/2,3110/2)).save("output" + str(number) + ".png")
    > print number
    > </code>


    >


    Ah, celular automata! Another of my on-off interest! I shall run this
    as soon as posible.
     
    placid, Jun 24, 2006
    #2
    1. Advertising

  3. defcon8

    defcon8 Guest

    defcon8, Jun 24, 2006
    #3
  4. defcon8

    Guest

    Few coding suggestions:
    - Don't mix spaces and tabs;
    - Don't write line (comments) too much long;
    - Don't post too much code here;
    - For this program maybe Pygame is more fit (to show the images in real
    time) instead of PIL;
    - Maybe Psyco can help speed up this program;
    - Maybe ShedSkin will support part of the cimg library, such kind of
    programs is fit for it :)

    Bye,
    bearophile
     
    , Jun 24, 2006
    #4
  5. defcon8

    defcon8 Guest

    blog-of-justin.blogspot.com

    Sorry for the error.
     
    defcon8, Jun 24, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Pleg
    Replies:
    0
    Views:
    541
  2. defcon8
    Replies:
    5
    Views:
    3,732
    defcon8
    Jun 24, 2006
  3. Replies:
    7
    Views:
    385
    defcon8
    May 14, 2006
  4. defcon8
    Replies:
    5
    Views:
    313
    defcon8
    Jun 24, 2006
  5. Ruby Quiz

    [QUIZ] Cellular Automata (#134)

    Ruby Quiz, Aug 10, 2007, in forum: Ruby
    Replies:
    25
    Views:
    412
    Yossef Mendelssohn
    Aug 15, 2007
Loading...

Share This Page