An elementary cellular automaton is a one-dimensional cellular automaton where there are two possible states (labeled 0 and 1) and the rule to determine the state of a cell in the next generation depends only on the current state of the cell and its two immediate neighbors. Those three values can be encoded with three bits.

The rules of evolution are then encoded with eight bits indicating the outcome of each of the eight possibilities 111, 110, 101, 100, 011, 010, 001 and 000 in this order. Thus for instance the rule 13 means that a state is updated to 1 only in the cases 011, 010 and 000, since 13 in binary is 0b00001101.



Task

Create a subroutine, program or function that allows to create and visualize the evolution of any of the 256 possible elementary cellular automaton of arbitrary space length and for any given initial state. You can demonstrate your solution with any automaton of your choice.

The space state should wrap: this means that the left-most cell should be considered as the right neighbor of the right-most cell, and reciprocally.

This task is basically a generalization of one-dimensional cellular automata.



See also
 Cellular automata (natureofcode.com)


 
#define NCELLS 400
#define border 16
dim as ubyte rule = 110
 
sub evolve( row as uinteger, rule as ubyte, pattern() as ubyte )
    dim as ubyte newp(NCELLS)
    dim as uinteger i
    dim as ubyte lookup
    for i = 0 to NCELLS-1
        pset (i + border, row + border ), pattern(i)*15
        lookup = 4*pattern((i-1) mod NCELLS) + 2*pattern(i) + pattern( (i+1) mod NCELLS )
        newp(i)=0
        if ( 2^lookup and rule )<>0 then newp(i) = 1
    next i
    for i = 0 to NCELLS-1
        pattern(i) = newp(i)
    next i
end sub
 
sub perform_simulation( rule as ubyte, pattern() as ubyte )
    dim as integer i
    for i = 1 to NCELLS
        evolve(i, rule, pattern())
    next i
end sub
 
sub reseed( pattern() as ubyte )
    dim as integer i
    for i = 0 to NCELLS-1
        pattern(i) = int(rnd+0.5)
    next i
end sub
 
sub display_text( rule as ubyte )
    locate 4,58 : print using "Rule ###";rule
    locate 6,53 : print " R: reshuffle seed "
    locate 8,53 : print " <,>: change rule "
    locate 10,53 : print " Q: quit "
end sub
 
screen 12
randomize timer
dim as boolean pattern(0 to NCELLS-1)
dim as string key="R"
 
do
    if key = "R" then
        cls
        reseed(pattern())
        perform_simulation(rule,pattern())
        display_text(rule)
    end if
    if key="<" then
        cls
        rule = (rule-1) mod 256
        reseed(pattern())
        perform_simulation(rule,pattern())
        display_text(rule)
    end if
    if key=">" then
        cls
        rule = (rule+1) mod 256
        reseed(pattern())
        perform_simulation(rule,pattern())
        display_text(rule)
    end if
    key = ucase(inkey)
loop until ucase(key) = "Q"