One-dimensional cellular automata: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Wren}}: Changed to Wren S/H)
(140 intermediate revisions by 68 users not shown)
Line 1:
{{task|Games}} [[Category:Cellular automata]]
Assume an array of cells with an initial distribution of live and dead cells, and imaginary cells off the end of the array having fixed values.
and imaginary cells off the end of the array having fixed values.
 
Cells in the next generation of the array are calculated based on the value of the cell and its left and right nearest neighbours in the current generation.
 
If, in the following table, a live cell is represented by 1 and a dead cell by 0 then to generate the value of the cell at a particular index in the array of cellular values you use the following table:
 
Line 13 ⟶ 15:
1'''1'''0 -> 1 # Needs one neighbour to survive
1'''1'''1 -> 0 # Starved to death.
 
;Related tasks:
* [[Elementary_cellular_automaton|Elementary cellular automaton]]
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">V gen = ‘_###_##_#_#_#_#__#__’.map(ch -> Int(ch == ‘#’))
L(n) 10
print(gen.map(cell -> (I cell != 0 {‘#’} E ‘_’)).join(‘’))
gen = [0] [+] gen [+] [0]
gen = (0 .< gen.len - 2).map(m -> Int(sum(:gen[m .+ 3]) == 2))</syntaxhighlight>
 
{{out}}
<pre>
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________
</pre>
 
=={{header|8th}}==
<syntaxhighlight lang="forth">
\ one-dimensional automaton
 
\ direct map of input state to output state:
{
" " : 32,
" #" : 32,
" # " : 32,
" ##" : 35,
"# " : 32,
"# #" : 35,
"## " : 35,
"###" : 32,
} var, lifemap
 
: transition \ s ix (r:s') -- (r:s')
>r dup r@ n:1- 3 s:slice
lifemap @ swap caseof
r> swap r@ -rot s:! >r ;
 
\ run over 'state' and generate new state
: gen \ s -- s'
clone >r
dup s:len 2 n:-
' transition 1 rot loop
drop r> ;
 
: life \ s -- s'
dup . cr gen ;
 
" ### ## # # # # # " ' life 10 times
bye
 
</syntaxhighlight>
 
=={{header|ACL2}}==
<langsyntaxhighlight lang="lisp">(defun rc-step-r (cells)
(if (endp (rest cells))
nil
Line 47 ⟶ 111:
nil
(prog2$ (pretty-row (first out))
(pretty-output (rest out)))))</langsyntaxhighlight>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">CHAR FUNC CalcCell(CHAR prev,curr,next)
IF prev='. AND curr='# AND next='# THEN
RETURN ('#)
ELSEIF prev='# AND curr='. AND next='# THEN
RETURN ('#)
ELSEIF prev='# AND curr='# AND next='. THEN
RETURN ('#)
FI
RETURN ('.)
 
PROC NextGeneration(CHAR ARRAY s)
BYTE i
CHAR prev,curr,next
 
IF s(0)<4 THEN RETURN FI
prev=s(1) curr=s(2) next=s(3)
i=2
DO
s(i)=CalcCell(prev,curr,next)
i==+1
IF i=s(0) THEN EXIT FI
prev=curr curr=next next=s(i+1)
OD
RETURN
 
PROC Main()
DEFINE MAXGEN="9"
CHAR ARRAY s=".###.##.#.#.#.#..#.."
BYTE i
 
FOR i=0 TO MAXGEN
DO
PrintF("Generation %I: %S%E",i,s)
IF i<MAXGEN THEN
NextGeneration(s)
FI
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/One-dimensional_cellular_automata.png Screenshot from Atari 8-bit computer]
<pre>
Generation 0: .###.##.#.#.#.#..#..
Generation 1: .#.#####.#.#.#......
Generation 2: ..##...##.#.#.......
Generation 3: ..##...###.#........
Generation 4: ..##...#.##.........
Generation 5: ..##....###.........
Generation 6: ..##....#.#.........
Generation 7: ..##.....#..........
Generation 8: ..##................
Generation 9: ..##................
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
 
procedure Cellular_Automata is
Line 91 ⟶ 209:
Step (Culture);
end loop;
end Cellular_Automata;</langsyntaxhighlight>
 
The implementation defines Petri dish type with Boolean items identifying whether a place is occupied by a living cell. State transition is determined by a simple Boolean expression of three arguments. Sample output:
The implementation defines Petri dish type with Boolean items
identifying whether a place is occupied by a living cell.
State transition is determined by a simple Boolean expression of three arguments.
{{out}}
<pre>
Generation 0 _###_##_#_#_#_#__#__
Line 105 ⟶ 227:
Generation 9 __##________________
</pre>
 
=={{header|ALGOL 68}}==
===Using the low level packed arrays of BITS manipulation operators===
Line 111 ⟶ 234:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of FORMATted transput}}
<langsyntaxhighlight lang="algol68">INT stop generation = 9;
INT universe width = 20;
FORMAT alive or dead = $b("#","_")$;
Line 153 ⟶ 276:
FI;
universe := next universe
OD</langsyntaxhighlight>
{{out}}
Output:
<pre>
Generation 0: _###_##_#_#_#_#__#__
Line 167 ⟶ 290:
Generation 9: __##________________
</pre>
 
===Using high level BOOL arrays===
{{works with|ALGOL 68|Revision 1 - no extensions to language used}}
Line 172 ⟶ 296:
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-1.18.0/algol68g-1.18.0-9h.tiny.el5.centos.fc11.i386.rpm/download 1.18.0-9h.tiny]}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of FORMATted transput}}
<langsyntaxhighlight lang="algol68">INT stop generation = 9;
<lang algol68>INT stop generation = 9;
INT upb universe = 20;
FORMAT alive or dead = $b("#","_")$;
Line 207 ⟶ 330:
next universe[UPB universe] := couple(universe[UPB universe - 1: ]);
universe := next universe
OD</langsyntaxhighlight>
{{out}}
Output:
<pre>
Generation 0: _###_##_#_#_#_#__#__
Line 221 ⟶ 344:
Generation 9: __##________________
</pre>
 
=={{header|ALGOL W}}==
Using a string to represent the cells and stopping when the next state is th same as the previous one.
<syntaxhighlight lang="algolw">begin
string(20) state;
string(20) nextState;
integer generation;
generation := 0;
state := "_###_##_#_#_#_#__#__";
while begin
write( i_w := 1, s_w := 1, "Generation ", generation, state );
nextState := "____________________";
for cPos := 1 until 18 do begin
string(3) curr;
curr := state( cPos - 1 // 3 );
nextState( cPos // 1 ) := if curr = "_##" or curr = "#_#" or curr = "##_" then "#" else "_"
end for_cPos ;
( state not = nextState )
end do begin
state := nextState;
generation := generation + 1
end while_not_finished
end.</syntaxhighlight>
{{out}}
<pre>
Generation 0 _###_##_#_#_#_#__#__
Generation 1 _#_#####_#_#_#______
Generation 2 __##___##_#_#_______
Generation 3 __##___###_#________
Generation 4 __##___#_##_________
Generation 5 __##____###_________
Generation 6 __##____#_#_________
Generation 7 __##_____#__________
Generation 8 __##________________
</pre>
 
=={{header|Amazing Hopper}}==
<p>Amazing Hopper flavour "BASICO", in spanish.</p>
<p>VERSION 1:</p>
<syntaxhighlight lang="c">
#include <basico.h>
 
algoritmo
tamaño de pila 65
x = 0
enlistar (0,0,1,1,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,0,\
1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0,\
1,1,0,0,0,0,0,1,0,1,0,1,1,1,1,1,1,1,0,0) mover a 'x'
x2 = x
decimales '0', token.separador ("")
iterar para ( k=1, #(k<=15), ++k )
imprimir ' #(utf8("Generación #")),k, "\t", x, NL '
iterar para ( j=2, #(j<60), ++j )
#(x2[j] = 0)
cuando ( #( (x[j-1]+x[j]+x[j+1])==2 ) ){
#(x2[j]=1)
}
siguiente
x = x2
siguiente
terminar
</syntaxhighlight>
{{out}}
<pre>
Generación #1 001110011010110111001111110111011111010011000001010111111100
Generación #2 001010011101111101001000011101110001100011000000101100000100
Generación #3 000100010111000110000000010111010001100011000000011100000000
Generación #4 000000001101000110000000001101100001100011000000010100000000
Generación #5 000000001110000110000000001111100001100011000000001000000000
Generación #6 000000001010000110000000001000100001100011000000000000000000
Generación #7 000000000100000110000000000000000001100011000000000000000000
Generación #8 000000000000000110000000000000000001100011000000000000000000
Generación #9 000000000000000110000000000000000001100011000000000000000000
Generación #10 000000000000000110000000000000000001100011000000000000000000
Generación #11 000000000000000110000000000000000001100011000000000000000000
Generación #12 000000000000000110000000000000000001100011000000000000000000
Generación #13 000000000000000110000000000000000001100011000000000000000000
Generación #14 000000000000000110000000000000000001100011000000000000000000
Generación #15 000000000000000110000000000000000001100011000000000000000000
</pre>
<p>VERSION 2:</p>
<syntaxhighlight lang="c">
#include <basico.h>
 
algoritmo
x={}
'0,0,1,1,1,0,0,1,1,0,1,0,1,1,0,1,1,1,0,0' anidar en lista 'x'
'1,1,1,1,1,1,0,1,1,1,0,1,1,1,1,1,0,1,0,0' anidar en lista 'x'
'1,1,0,0,0,0,0,1,0,1,0,1,1,1,1,1,1,1,0,0' anidar en lista 'x'
 
x2 = x, k=10
decimales '0', token.separador ("")
iterar
imprimir ' #(utf8("Generación #")), #(11-k), "\t", x, NL '
iterar para ( j=2, #(j<60), ++j )
#( x2[j] = ((x[j-1]+x[j]+x[j+1])==2) )
siguiente
x = x2
mientras ' k-- '
terminar
 
</syntaxhighlight>
{{out}}
<pre>
Generación #1 001110011010110111001111110111011111010011000001010111111100
Generación #2 001010011101111101001000011101110001100011000000101100000100
Generación #3 000100010111000110000000010111010001100011000000011100000000
Generación #4 000000001101000110000000001101100001100011000000010100000000
Generación #5 000000001110000110000000001111100001100011000000001000000000
Generación #6 000000001010000110000000001000100001100011000000000000000000
Generación #7 000000000100000110000000000000000001100011000000000000000000
Generación #8 000000000000000110000000000000000001100011000000000000000000
Generación #9 000000000000000110000000000000000001100011000000000000000000
Generación #10 000000000000000110000000000000000001100011000000000000000000
Generación #11 000000000000000110000000000000000001100011000000000000000000
 
</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">evolve: function [arr][
ary: [0] ++ arr ++ [0]
ret: new []
loop 1..(size ary)-2 'i [
a: ary\[i-1]
b: ary\[i]
c: ary\[i+1]
 
if? 2 = a+b+c -> 'ret ++ 1
else -> 'ret ++ 0
]
ret
]
 
printIt: function [arr][
print replace replace join map arr 'n -> to :string n "0" "_" "1" "#"
]
 
arr: [0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0]
printIt arr
 
newGen: evolve arr
while [newGen <> arr][
arr: newGen
newGen: evolve arr
printIt newGen
]</syntaxhighlight>
 
{{out}}
 
<pre>_###_##_#_#_#_#__#__
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________</pre>
 
=={{header|AutoHotkey}}==
ahk [http://www.autohotkey.com/forum/viewtopic.php?t=44657&postdays=0&postorder=asc&start=147 discussion]
<langsyntaxhighlight lang="autohotkey">n := 22, n1 := n+1, v0 := v%n1% := 0 ; set grid dimensions, and fixed cells
 
Loop % n { ; draw a line of checkboxes
Line 246 ⟶ 528:
 
GuiClose: ; exit when GUI is closed
ExitApp</langsyntaxhighlight>
 
=={{header|AWK}}==
 
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
BEGIN {
edge = 1
Line 319 ⟶ 601:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Sample output:
<pre>
0: . @ @ @ . @ @ . @ . @ . @ . @ . . @ . .
1: . @ . @ @ @ @ @ . @ . @ . @ . . . . . .
Line 332 ⟶ 615:
8: . . @ @ . . . . . . . . . . . . . . . .
9: . . @ @ . . . . . . . . . . . . . . . .
</pre>
 
<syntaxhighlight lang="awk">Another new solution (twice size as previous solution) :
cat automata.awk :
 
#!/usr/local/bin/gawk -f
 
# User defined functions
function ASCII_to_Binary(str_) {
gsub("_","0",str_); gsub("@","1",str_)
return str_
}
 
function Binary_to_ASCII(bit_) {
gsub("0","_",bit_); gsub("1","@",bit_)
return bit_
}
 
function automate(b1,b2,b3) {
a = and(b1,b2,b3)
b = or(b1,b2,b3)
c = xor(b1,b2,b3)
d = a + b + c
return d == 1 ? 1 : 0
}
 
# For each line in input do
{
str_ = $0
gen = 0
taille = length(str_)
print "0: " str_
do {
gen ? str_previous = str_ : str_previous = ""
gen += 1
str_ = ASCII_to_Binary(str_)
split(str_,tab,"")
str_ = and(tab[1],tab[2])
for (i=1; i<=taille-2; i++) {
str_ = str_ automate(tab[i],tab[i+1],tab[i+2])
}
str_ = str_ and(tab[taille-1],tab[taille])
print gen ": " Binary_to_ASCII(str_)
} while (str_ != str_previous)
}
</syntaxhighlight>
 
{{out}}
<pre>
$ echo ".@@@.@@.@.@.@.@..@.." | awk -f automata.awk
0: .@@@.@@.@.@.@.@..@..
1: _@_@@@@@_@_@_@______
2: __@@___@@_@_@_______
3: __@@___@@@_@________
4: __@@___@_@@_________
5: __@@____@@@_________
6: __@@____@_@_________
7: __@@_____@__________
8: __@@________________
9: __@@________________
</pre>
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
{{trans|Locomotive BASIC}}
<syntaxhighlight lang="qbasic">100 HOME
110 n = 10
120 READ w : DIM x(w+1),x2(w+1) : FOR i = 1 TO w : READ x(i) : NEXT
130 FOR k = 1 TO n
140 FOR j = 1 TO w
150 IF x(j) THEN PRINT "#";
155 IF NOT x(j) THEN PRINT "_";
160 IF x(j-1)+x(j)+x(j+1) = 2 THEN x2(j) = 1
165 IF x(j-1)+x(j)+x(j+1) <> 2 THEN x2(j) = 0
170 NEXT : PRINT
180 FOR j = 1 TO w : x(j) = x2(j) : NEXT
190 NEXT
200 DATA 20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0</syntaxhighlight>
 
==={{header|BASIC256}}===
<syntaxhighlight lang="basic256">arraybase 1
dim start = {0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0}
dim sgtes(start[?]+1)
 
for k = 0 to 9
print "Generation "; k; ": ";
for j = 0 to start[?]-1
 
if start[j] then print "#"; else print "_";
if start[j-1] + start[j] + start[j+1] = 2 then sgtes[j] = 1 else sgtes[j] = 0
next j
print
for j = 0 to start[?]-1
start[j] = sgtes[j]
next j
next k</syntaxhighlight>
 
==={{header|BBC BASIC}}===
<syntaxhighlight lang="bbcbasic"> DIM rule$(7)
rule$() = "0", "0", "0", "1", "0", "1", "1", "0"
now$ = "01110110101010100100"
FOR generation% = 0 TO 9
PRINT "Generation " ; generation% ":", now$
next$ = ""
FOR cell% = 1 TO LEN(now$)
next$ += rule$(EVAL("%"+MID$("0"+now$+"0", cell%, 3)))
NEXT cell%
SWAP now$, next$
NEXT generation%</syntaxhighlight>
{{out}}
<pre>Generation 0: 01110110101010100100
Generation 1: 01011111010101000000
Generation 2: 00110001101010000000
Generation 3: 00110001110100000000
Generation 4: 00110001011000000000
Generation 5: 00110000111000000000
Generation 6: 00110000101000000000
Generation 7: 00110000010000000000
Generation 8: 00110000000000000000
Generation 9: 00110000000000000000</pre>
 
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{works with|BASICA}}
{{works with|GW-BASIC}}
{{works with|MSX BASIC}}
{{works with|PC-BASIC|any}}
{{works with|QBasic}}
{{works with|QuickBasic}}
{{works with|Quite BASIC}}
<syntaxhighlight lang="qbasic">100 CLS
110 LET n = 10
120 READ w
121 DIM x(w+1): DIM x2(w+1)
122 FOR i = 1 TO w : READ x(i) : NEXT i
130 FOR k = 1 TO n
140 FOR j = 1 TO w
150 IF x(j) THEN PRINT "#"; ELSE PRINT "_";
160 IF x(j-1)+x(j)+x(j+1) = 2 THEN LET x2(j) = 1 ELSE LET x2(j) = 0
170 NEXT j
171 PRINT
180 FOR j = 1 TO w : LET x(j) = x2(j) : NEXT j
190 NEXT k
200 DATA 20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0
210 END</syntaxhighlight>
 
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">#define SIZE 640
 
randomize timer
 
dim as ubyte arr(0 to SIZE-1, 0 to 1)
dim as uinteger i
for i = 0 to SIZE - 1 'initialise array with zeroes and ones
arr(i, 0)=int(rnd+0.5)
next i
 
screen 12 'display graphically
 
dim as string ch=" "
dim as uinteger j = 0, cur = 0, nxt, prv, neigh
while not ch = "q" or ch = "Q"
for i = 0 to SIZE - 1
pset(i, j), 8+7*arr(i,cur) 'print off cells as grey, on cells as bright white
nxt = (i + 1) mod SIZE
prv = (i - 1)
if prv < 0 then prv = SIZE - 1 'let's have a wrap-around array for fun
neigh = arr(prv, cur) + arr(nxt, cur)
if arr(i, cur) = 0 then 'evolution rules
if neigh = 2 then
arr(i, 1-cur) = 1
else
arr(i, 1-cur) = 0
end if
else
if neigh = 0 or neigh = 2 then
arr(i, 1-cur) = 0
else
arr(i, 1-cur) = 1
end if
end if
next i
j = j + 1
cur = 1 - cur
do
ch = inkey
if ch <> "" then exit do 'press any key to advance the sim
'or Q to exit
loop
wend</syntaxhighlight>
 
==={{header|GFA Basic}}===
<syntaxhighlight lang="text">
'
' One Dimensional Cellular Automaton
'
start$="01110110101010100100"
max_cycles%=20 ! give a maximum depth
'
' Global variables hold the world, with two rows
' world! is set up with 2 extra cells width, so there is a FALSE on either side
' cur% gives the row for current world,
' new% gives the row for the next world.
'
size%=LEN(start$)
DIM world!(size%+2,2)
cur%=0
new%=1
clock%=0
'
@setup_world(start$)
OPENW 1
CLEARW 1
DO
@display_world
@update_world
EXIT IF @same_state
clock%=clock%+1
EXIT IF clock%>max_cycles% ! safety net
LOOP
~INP(2)
CLOSEW 1
'
' parse given string to set up initial states in world
' -- assumes world! is of correct size
'
PROCEDURE setup_world(defn$)
LOCAL i%
' clear out the array
ARRAYFILL world!(),FALSE
' for each 1 in string, set cell to true
FOR i%=1 TO LEN(defn$)
IF MID$(defn$,i%,1)="1"
world!(i%,0)=TRUE
ENDIF
NEXT i%
' set references to cur and new
cur%=0
new%=1
RETURN
'
' Display the world
'
PROCEDURE display_world
LOCAL i%
FOR i%=1 TO size%
IF world!(i%,cur%)
PRINT "#";
ELSE
PRINT ".";
ENDIF
NEXT i%
PRINT ""
RETURN
'
' Create new version of world
'
PROCEDURE update_world
LOCAL i%
FOR i%=1 TO size%
world!(i%,new%)=@new_state(@get_value(i%))
NEXT i%
' reverse cur/new
cur%=1-cur%
new%=1-new%
RETURN
'
' Test if cur/new states are the same
'
FUNCTION same_state
LOCAL i%
FOR i%=1 TO size%
IF world!(i%,cur%)<>world!(i%,new%)
RETURN FALSE
ENDIF
NEXT i%
RETURN TRUE
ENDFUNC
'
' Return new state of cell given value
'
FUNCTION new_state(value%)
SELECT value%
CASE 0,1,2,4,7
RETURN FALSE
CASE 3,5,6
RETURN TRUE
ENDSELECT
ENDFUNC
'
' Compute value for cell + neighbours
'
FUNCTION get_value(cell%)
LOCAL result%
result%=0
IF world!(cell%-1,cur%)
result%=result%+4
ENDIF
IF world!(cell%,cur%)
result%=result%+2
ENDIF
IF world!(cell%+1,cur%)
result%=result%+1
ENDIF
RETURN result%
ENDFUNC</syntaxhighlight>
 
==={{header|GW-BASIC}}===
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
 
==={{header|Liberty BASIC}}===
{{works with|Just BASIC}}
{{works with|Run BASIC}}
<syntaxhighlight lang="lb">' [RC] 'One-dimensional cellular automata'
 
' does not wrap so fails for some rules
rule$ ="00010110" ' Rule 22 decimal
 
state$ ="0011101101010101001000"
 
for j =1 to 20
print state$
oldState$ =state$
state$ ="0"
for k =2 to len( oldState$) -1
NHood$ =mid$( oldState$, k -1, 3) ' pick 3 char neighbourhood and turn binary string to decimal
vNHood =0
for kk =3 to 1 step -1
vNHood =vNHood +val( mid$( NHood$, kk, 1)) *2^( 3 -kk)
next kk
' .... & use it to index into rule$ to find appropriate new value
state$ =state$ +mid$( rule$, vNHood +1, 1)
next k
state$ =state$ +"0"
 
next j
 
end</syntaxhighlight>
 
==={{header|Locomotive Basic}}===
<syntaxhighlight lang="locobasic">10 MODE 1:n=10:READ w:DIM x(w+1),x2(w+1):FOR i=1 to w:READ x(i):NEXT
20 FOR k=1 TO n
30 FOR j=1 TO w
40 IF x(j) THEN PRINT "#"; ELSE PRINT "_";
50 IF x(j-1)+x(j)+x(j+1)=2 THEN x2(j)=1 ELSE x2(j)=0
60 NEXT:PRINT
70 FOR j=1 TO w:x(j)=x2(j):NEXT
80 NEXT
90 DATA 20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0</syntaxhighlight>
 
{{out}}
[[File:Cellular automaton locomotive basic.png]]
 
==={{header|MSX Basic}}===
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
 
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">EnableExplicit
Dim cG.i(21)
Dim nG.i(21)
Define.i n, Gen
DataSection
Data.i 0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0
EndDataSection
For n=1 To 20
Read.i cG(n)
Next
OpenConsole()
Repeat
Print("Generation "+Str(Gen)+": ")
For n=1 To 20
Print(Chr(95-cG(n)*60))
Next
Gen +1
PrintN("")
For n=1 To 20
If (cG(n) And (cG(n-1) XOr cg(n+1))) Or (Not cG(n) And (cG(n-1) And cg(n+1)))
nG(n)=1
Else
nG(n)=0
EndIf
Next
CopyArray(nG(), cG())
Until Gen > 9
PrintN("Press any key to exit"): Repeat: Until Inkey() <> ""</syntaxhighlight>
{{out}}
<pre>Generation 0: _###_##_#_#_#_#__#__
Generation 1: _#_#####_#_#_#______
Generation 2: __##___##_#_#_______
Generation 3: __##___###_#________
Generation 4: __##___#_##_________
Generation 5: __##____###_________
Generation 6: __##____#_#_________
Generation 7: __##_____#__________
Generation 8: __##________________
Generation 9: __##________________</pre>
 
==={{header|QBasic}}===
{{works with|QBasic|1.1}}
{{works with|QuickBasic|4.5}}
{{trans|Java}}
<langsyntaxhighlight lang="qbasic">DECLARE FUNCTION life$ (lastGen$)
DECLARE FUNCTION getNeighbors! (group$)
CLS
Line 389 ⟶ 1,073:
NEXT i
life$ = newGen$
END FUNCTION</langsyntaxhighlight>
{{out}}
Output:
<pre>Generation 0 : _###_##_#_#_#_#__#__
Generation 1 : _#_#####_#_#_#______
Line 402 ⟶ 1,086:
Generation 9 : __##________________</pre>
 
==={{header|BBCQuite BASIC}}===
The [[#Chipmunk Basic|Chipmunk Basic]] solution works without any changes.
<lang bbcbasic> DIM rule$(7)
 
rule$() = "0", "0", "0", "1", "0", "1", "1", "0"
==={{header|Run BASIC}}===
The [[#Liberty BASIC|Liberty BASIC]] solution works without any changes.
now$ = "01110110101010100100"
 
==={{header|Sinclair ZX81 BASIC}}===
FOR generation% = 0 TO 9
Works with the unexpanded (1k RAM) ZX81.
PRINT "Generation " ; generation% ":", now$
<syntaxhighlight lang="basic"> 10 LET N$="01110110101010100100"
next$ = ""
20 LET G=1
FOR cell% = 1 TO LEN(now$)
30 PRINT N$
next$ += rule$(EVAL("%"+MID$("0"+now$+"0", cell%, 3)))
40 LET O$=N$
NEXT cell%
50 LET N$=""
SWAP now$, next$
60 PRINT AT 0,28;G
NEXT generation%</lang>
70 LET N=0
80 FOR I=1 TO LEN O$
90 IF I=1 THEN GOTO 120
100 LET N=VAL O$(I-1)
110 IF I=LEN O$ THEN GOTO 130
120 LET N=N+VAL O$(I+1)
130 IF N=0 THEN LET N$=N$+"0"
140 IF N=1 THEN LET N$=N$+O$(I)
150 IF N=2 THEN LET N$=N$+STR$ NOT VAL O$(I)
160 PRINT AT 0,I-1;N$(I)
170 NEXT I
180 LET G=G+1
190 IF N$<>O$ THEN GOTO 40</syntaxhighlight>
{{out}}
The program overwrites each cell on the screen as it updates it (which it does quite slowly—there is no difficulty about watching what it is doing), with a counter to the right showing the generation it is currently working on. When it is part of the way through, for example, the display looks like this:
<pre>00110001011000000000 5</pre>
It halts when a stable state has been reached:
<pre>00110000000000000000 9</pre>
 
==={{header|Visual Basic .NET}}===
This implementation is run from the command line. The command is followed by a string of either 1's or #'s for an active cell, or 0's or _'s for an inactive one.
 
<syntaxhighlight lang="visual basic .net">Imports System.Text
 
Module CellularAutomata
 
Private Enum PetriStatus
Active
Stable
Dead
End Enum
 
Function Main(ByVal cmdArgs() As String) As Integer
If cmdArgs.Length = 0 Or cmdArgs.Length > 1 Then
Console.WriteLine("Command requires string of either 1s and 0s or #s and _s.")
Return 1
End If
 
Dim petriDish As BitArray
 
Try
petriDish = InitialisePetriDish(cmdArgs(0))
Catch ex As Exception
Console.WriteLine(ex.Message)
Return 1
End Try
 
Dim generation As Integer = 0
Dim ps As PetriStatus = PetriStatus.Active
 
Do While True
If ps = PetriStatus.Stable Then
Console.WriteLine("Sample stable after {0} generations.", generation - 1)
Exit Do
Else
Console.WriteLine("{0}: {1}", generation.ToString("D3"), BuildDishString(petriDish))
If ps = PetriStatus.Dead Then
Console.WriteLine("Sample dead after {0} generations.", generation)
Exit Do
End If
End If
 
ps = GetNextGeneration(petriDish)
generation += 1
Loop
 
Return 0
End Function
 
Private Function InitialisePetriDish(ByVal Sample As String) As BitArray
Dim PetriDish As New BitArray(Sample.Length)
Dim dead As Boolean = True
 
For i As Integer = 0 To Sample.Length - 1
Select Case Sample.Substring(i, 1)
Case "1", "#"
PetriDish(i) = True
dead = False
Case "0", "_"
PetriDish(i) = False
Case Else
Throw New Exception("Illegal value in string position " & i)
Return Nothing
End Select
Next
 
If dead Then
Throw New Exception("Entered sample is dead.")
Return Nothing
End If
 
Return PetriDish
End Function
 
Private Function GetNextGeneration(ByRef PetriDish As BitArray) As PetriStatus
Dim petriCache = New BitArray(PetriDish.Length)
Dim neighbours As Integer
Dim stable As Boolean = True
Dim dead As Boolean = True
 
For i As Integer = 0 To PetriDish.Length - 1
neighbours = 0
If i > 0 AndAlso PetriDish(i - 1) Then neighbours += 1
If i < PetriDish.Length - 1 AndAlso PetriDish(i + 1) Then neighbours += 1
 
petriCache(i) = (PetriDish(i) And neighbours = 1) OrElse (Not PetriDish(i) And neighbours = 2)
If PetriDish(i) <> petriCache(i) Then stable = False
If petriCache(i) Then dead = False
Next
 
PetriDish = petriCache
 
If dead Then Return PetriStatus.Dead
If stable Then Return PetriStatus.Stable
Return PetriStatus.Active
 
End Function
 
Private Function BuildDishString(ByVal PetriDish As BitArray) As String
Dim sw As New StringBuilder()
For Each b As Boolean In PetriDish
sw.Append(IIf(b, "#", "_"))
Next
 
Return sw.ToString()
End Function
End Module</syntaxhighlight>
 
Output:
<pre>C:\>CellularAutomata _###_##_#_#_#_#__#__
<pre>Generation 0: 01110110101010100100
000: _###_##_#_#_#_#__#__
Generation 1: 01011111010101000000
001: _#_#####_#_#_#______
Generation 2: 00110001101010000000
002: __##___##_#_#_______
Generation 3: 00110001110100000000
003: __##___###_#________
Generation 4: 00110001011000000000
004: __##___#_##_________
Generation 5: 00110000111000000000
005: __##____###_________
Generation 6: 00110000101000000000
006: __##____#_#_________
Generation 7: 00110000010000000000
007: __##_____#__________
Generation 8: 00110000000000000000
008: __##________________
Generation 9: 00110000000000000000</pre>
Sample stable after 8 generations.</pre>
 
==={{header|Yabasic}}===
{{trans|Locomotive_Basic}}
<syntaxhighlight lang="yabasic">10 n=10:READ w:DIM x(w+1),x2(w+1):FOR i=1 to w:READ x(i):NEXT
20 FOR k=1 TO n
30 FOR j=1 TO w
40 IF x(j) THEN PRINT "#"; ELSE PRINT "_"; END IF
50 IF x(j-1)+x(j)+x(j+1)=2 THEN x2(j)=1 ELSE x2(j)=0 END IF
60 NEXT:PRINT
70 FOR j=1 TO w:x(j)=x2(j):NEXT
80 NEXT
90 DATA 20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0</syntaxhighlight>
 
Other solution
<syntaxhighlight lang="yabasic">start$ = "0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0"
 
dim x$(1)
 
for k = 1 to 10
n = token(start$, x$(), ",")
redim x$(n+1)
start$ = ""
for j = 1 to n
if val(x$(j)) then print "#"; else print "_"; end if
test = abs(val(x$(j-1)) + val(x$(j)) + val(x$(j+1)) = 2)
start$ = start$ + str$(test) + ","
next j
print
next k</syntaxhighlight>
 
=={{header|Batch File}}==
This implementation will not stop showing generations, unless the cellular automata is already stable.
<syntaxhighlight lang="dos">@echo off
setlocal enabledelayedexpansion
 
::THE MAIN THING
call :one-dca __###__##_#_##_###__######_###_#####_#__##_____#_#_#######__
pause>nul
exit /b
::/THE MAIN THING
 
::THE PROCESSOR
:one-dca
echo.&set numchars=0&set proc=%1
 
::COUNT THE NUMBER OF CHARS
set bef=%proc:_=_,%
set bef=%bef:#=#,%
set bef=%bef:~0,-1%
for %%x in (%bef%) do set /a numchars+=1
 
set /a endchar=%numchars%-1
:nextgen
echo. ^| %proc% ^|
set currnum=0
set newgen=
:editeachchar
set neigh=0
set /a testnum2=%currnum%+1
set /a testnum1=%currnum%-1
if %currnum%==%endchar% (
set testchar=!proc:~%testnum1%,1!
if !testchar!==# (set neigh=1)
) else (
if %currnum%==0 (
set testchar=%proc:~1,1%
if !testchar!==# (set neigh=1)
) else (
set testchar1=!proc:~%testnum1%,1!
set testchar2=!proc:~%testnum2%,1!
if !testchar1!==# (set /a neigh+=1)
if !testchar2!==# (set /a neigh+=1)
)
)
if %neigh%==0 (set newgen=%newgen%_)
if %neigh%==1 (
set testchar=!proc:~%currnum%,1!
set newgen=%newgen%!testchar!
)
if %neigh%==2 (
set testchar=!proc:~%currnum%,1!
if !testchar!==# (set newgen=%newgen%_) else (set newgen=%newgen%#)
)
if %currnum%==%endchar% (goto :cond) else (set /a currnum+=1&goto :editeachchar)
 
:cond
if %proc%==%newgen% (echo.&echo ...The sample is now stable.&goto :EOF)
set proc=%newgen%
goto :nextgen
::/THE (LLLLLLOOOOOOOOOOOOONNNNNNNNGGGGGG.....) PROCESSOR</syntaxhighlight>
{{out}}
<pre> | __###__##_#_##_###__######_###_#####_#__##_____#_#_#######__ |
| __#_#__###_#####_#__#____###_###___##___##______#_##_____#__ |
| ___#___#_###___##________#_###_#___##___##_______###________ |
| ________##_#___##_________##_##____##___##_______#_#________ |
| ________###____##_________#####____##___##________#_________ |
| ________#_#____##_________#___#____##___##__________________ |
| _________#_____##__________________##___##__________________ |
| _______________##__________________##___##__________________ |
 
...The sample is now stable.</pre>
 
=={{header|Befunge}}==
<langsyntaxhighlight lang="befunge">v
" !!! !! ! ! ! ! ! " ,*25 <v
" " ,*25,,,,,,,,,,,,,,,,,,,,<v
Line 444 ⟶ 1,358:
^ >$$$$320p10g1+:9`v > >$"!"> 20g10g1+p 20g1+:20p
^ v_10p10g
> ^</langsyntaxhighlight>
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat"> ( ( evolve
= n z
. @( !arg
Line 476 ⟶ 1,390:
& evolve$!S:?S
)
);</langsyntaxhighlight>
{{out}}
Output:
<pre>11101101010101001001
10111110101010000001
Line 487 ⟶ 1,401:
11000000100000000001
11000000000000000001</pre>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
 
Line 515 ⟶ 1,430:
do { printf(c + 1); } while (evolve(c + 1, b + 1, sizeof(c) - 3));
return 0;
}</syntaxhighlight>
}</lang>output
{{out}}
<pre>###_##_#_#_#_#__#__
#_#####_#_#_#______
Line 527 ⟶ 1,443:
 
Similar to above, but without a backup string:
<langsyntaxhighlight lang="c">#include <stdio.h>
char trans[] = "___#_##_";
Line 553 ⟶ 1,469:
do { printf(c + 1); } while (evolve(c + 1, sizeof(c) - 3));
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
 
namespace prog
{
class MainClass
{
const int n_iter = 10;
static int[] f = { 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 };
public static void Main (string[] args)
{
for( int i=0; i<f.Length; i++ )
Console.Write( f[i]==0 ? "-" : "#" );
Console.WriteLine("");
int[] g = new int[f.Length];
for( int n=n_iter; n!=0; n-- )
{
for( int i=1; i<f.Length-1; i++ )
{
if ( (f[i-1] ^ f[i+1]) == 1 ) g[i] = f[i];
else if ( f[i] == 0 && (f[i-1] & f[i+1]) == 1 ) g[i] = 1;
else g[i] = 0;
}
g[0] = ( (f[0] & f[1]) == 1 ) ? 1 : 0;
g[g.Length-1] = ( (f[f.Length-1] & f[f.Length-2]) == 1 ) ? 1 : 0;
int[] tmp = f;
f = g;
g = tmp;
for( int i=0; i<f.Length; i++ )
Console.Write( f[i]==0 ? "-" : "#" );
Console.WriteLine("");
}
}
}
}</syntaxhighlight>
 
=={{header|C++}}==
Uses std::bitset for efficient packing of bit values.
<langsyntaxhighlight Cpplang="cpp">#include <iostream>
#include <bitset>
#include <string>
Line 585 ⟶ 1,542:
std::cout << std::endl;
}
}</langsyntaxhighlight>
 
{{out}}
Output:
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
Line 598 ⟶ 1,555:
__##________________
__##________________</pre>
=={{header|C sharp}}==
<lang csharp>using System;
using System.Collections.Generic;
 
=={{header|Ceylon}}==
namespace prog
<syntaxhighlight lang="ceylon">shared abstract class Cell(character) of alive | dead {
{
shared Character character;
class MainClass
string => character.string;
{
shared formal Cell opposite;
const int n_iter = 10;
}
static int[] f = { 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 };
 
shared object alive extends Cell('#') {
opposite => dead;
}
shared object dead extends Cell('_') {
opposite => alive;
}
 
shared Map<Character, Cell> cellsByCharacter = map { for (cell in `Cell`.caseValues) cell.character->cell };
 
shared class Automata1D({Cell*} initialCells) {
value permanentFirstCell = initialCells.first else dead;
value permanentLastCell = initialCells.last else dead;
value cells = Array { *initialCells.rest.exceptLast };
shared Boolean evolve() {
value newCells = Array {
public static void Main (string[] args)
for (index->cell in cells.indexed)
{
let (left = cells[index - 1] else permanentFirstCell,
for( int i=0; i<f.Length; i++ )
right = cells[index + 1] else permanentLastCell,
Console.Write( f[i]==0 ? "-" : "#" );
neighbours = [left, right],
Console.WriteLine("");
bothAlive = neighbours.every(alive.equals),
bothDead = neighbours.every(dead.equals))
int[] g = new int[f.Length];
if (bothAlive)
for( int n=n_iter; n!=0; n-- )
then cell.opposite
{
else if (cell == alive && bothDead)
for( int i=1; i<f.Length-1; i++ )
{then dead
else cell
if ( (f[i-1] ^ f[i+1]) == 1 ) g[i] = f[i];
};
else if ( f[i] == 0 && (f[i-1] & f[i+1]) == 1 ) g[i] = 1;
else g[i] = 0;
if (newCells == cells) {
}
return false;
g[0] = ( (f[0] & f[1]) == 1 ) ? 1 : 0;
g[g.Length-1] = ( (f[f.Length-1] & f[f.Length-2]) == 1 ) ? 1 : 0;
int[] tmp = f;
f = g;
g = tmp;
for( int i=0; i<f.Length; i++ )
Console.Write( f[i]==0 ? "-" : "#" );
Console.WriteLine("");
}
}
newCells.copyTo(cells);
return true;
}
string => permanentFirstCell.string + "".join(cells) + permanentLastCell.string;
}
 
shared Automata1D? automata1d(String string) =>
let (cells = string.map((Character element) => cellsByCharacter[element]))
if (cells.every((Cell? element) => element exists))
then Automata1D(cells.coalesced)
else null;
 
shared void run() {
 
assert (exists automata = automata1d("__###__##_#_##_###__######_###_#####_#__##_____#_#_#######__"));
variable value generation = 0;
print("generation ``generation`` ``automata``");
while (automata.evolve() && generation<10) {
print("generation `` ++generation `` ``automata``");
}
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">(ns one-dimensional-cellular-automata
(:require (clojure.contrib (string :as s))))
 
Line 655 ⟶ 1,640:
'()
(cons cells (generate (dec n) (next-gen cells)))))
</syntaxhighlight>
</lang>
<langsyntaxhighlight lang="clojure">one-dimensional-cellular-automata> (doseq [cells (generate 9 "_###_##_#_#_#_#__#__")]
(println cells))
_###_##_#_#_#_#__#__
Line 668 ⟶ 1,653:
__##________________
nil
</syntaxhighlight>
</lang>
 
Another way:
 
<syntaxhighlight lang="clojure">#!/usr/bin/env lein-exec
 
(require '[clojure.string :as str])
 
(def first-genr "_###_##_#_#_#_#__#__")
 
(def hospitable #{"_##"
"##_"
"#_#"})
 
(defn compute-next-genr
[genr]
(let [genr (str "_" genr "_")
groups (map str/join (partition 3 1 genr))
next-genr (for [g groups]
(if (hospitable g) \# \_))]
(str/join next-genr)))
 
;; ---------------- main -----------------
(loop [g first-genr
i 0]
(if (not= i 10)
(do (println g)
(recur (compute-next-genr g)
(inc i)))))</syntaxhighlight>
 
Yet another way, easier to understand
 
<syntaxhighlight lang="clojure">
(def rules
{
[0 0 0] 0
[0 0 1] 0
[0 1 0] 0
[0 1 1] 1
[1 0 0] 0
[1 0 1] 1
[1 1 0] 1
[1 1 1] 0
})
 
(defn nextgen [gen]
(concat [0]
(->> gen
(partition 3 1)
(map vec)
(map rules))
[0]))
 
; Output time!
(doseq [g (take 10 (iterate nextgen [0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0]))]
(println g))
</syntaxhighlight>
 
=={{header|COBOL}}==
 
<langsyntaxhighlight lang="cobol">
Identification division.
Program-id. rc-1d-cell.
Line 780 ⟶ 1,822:
end-perform
.
</syntaxhighlight>
</lang>
 
Sample output:
 
{{out}}
<pre>
0: .@@@.@@.@.@.@.@..@..
1: .@.@@@@@.@.@.@......
Line 793 ⟶ 1,835:
7: ..@@.....@..........
8: ..@@................
9: ..@@................</pre>
 
=pre>###_##_#_#_#_#__#__
=={{header|CoffeeScript}}==
#_#####_#_#_#______
<lang coffeescript>
_##___##_#_#_______
_##___###_#________
_##___#_##_________
_##____###_________
_##____#_#_________
_##_____#__________
_##________________={{header|CoffeeScript}}==
<syntaxhighlight lang="coffeescript">
# We could cheat and count the bits, but let's keep this general.
# . = dead, # = alive, middle cells survives iff one of the configurations
Line 829 ⟶ 1,879:
simulate (c == '#' for c in ".###.##.#.#.#.#..#..")
</syntaxhighlight>
</lang>
{{out}}
output
<langpre>
> coffee cellular_automata.coffee
.###.##.#.#.#.#..#..
Line 843 ⟶ 1,893:
..##................
equilibrium achieved
</langpre>
 
 
 
=={{header|Common Lisp}}==
Based upon the Ruby version.
<langsyntaxhighlight lang="lisp">(defun value (x)
(assert (> (length x) 1))
(coerce x 'simple-bit-vector))
Line 874 ⟶ 1,926:
do (princ (if (zerop (bit value i)) #\. #\#)
stream))
(terpri stream))</langsyntaxhighlight>
 
<langsyntaxhighlight lang="lisp">CL-USER> (loop for previous-value = nil then value
for value = #*01110110101010100100 then (next-cycle value)
until (equalp value previous-value)
Line 888 ⟶ 1,940:
..##....#.#.........
..##.....#..........
..##................</langsyntaxhighlight>
 
=={{header|D}}==
<syntaxhighlight lang="d">void main() {
<lang d>import std.stdio, std.algorithm;
import std.stdio, std.algorithm;
 
enum nGenerations = 10;
void main() {
enum ngenerations = 10;
enum initial = "0011101101010101001000";
enum table = "00010110";
Line 900 ⟶ 1,952:
char[initial.length + 2] A = '0', B = '0';
A[1 .. $-1] = initial;
foreach (immutable _; 0 .. ngenerationsnGenerations) {
foreach (immutable i; 1 .. A.length - 1) {
write(A[i] == '0' ? '_' : '#');
intconst val = (A[i-1]-'0' << 2) | (A[i]-'0' << 1) | (A[i+1]-'0');
B[i] = table[val];
}
A.swap(A, B);
writeln();
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>__###_##_#_#_#_#__#___
__#_#####_#_#_#_______
Line 923 ⟶ 1,975:
 
===Alternative Version===
{{trans|Perl 6Raku}}
<syntaxhighlight lang="d">void main() {
<lang d>import std.stdio, std.algorithm, std.array, std.range;
import std.stdio, std.algorithm, std.range;
 
void main() {
auto A = "_###_##_#_#_#_#__#__".map!q{a == '#'}.array;
auto B = A.dup;
Line 932 ⟶ 1,984:
do {
A.map!q{ "_#"[a] }.writeln;
A.zip(A, A.cycle.drop(1), A.cycle.drop(A.length - 1))
//.map!(t => [t[]].sum == 2).copy(B);
.map!q{ a[0] + a[1] + a[2] == 2 }.copy(B);
A.swap(B);
} while (A != B);
}</langsyntaxhighlight>
{{out}}
<pre>_###_##_#_#_#_#__#__
Line 952 ⟶ 2,003:
This version saves memory representing the state in an array of bits. For a higher performance a SWAR approach should be tried.
{{trans|C++}}
<syntaxhighlight lang="d">void main() {
<lang d>import std.stdio, std.algorithm, std.array, std.range, std.bitmanip;
import std.stdio, std.algorithm, std.range, std.bitmanip;
 
immutable initial = "__###_##_#_#_#_#__#___";
enum numGenerationsnGenerations = 10;
 
void main() {
BitArray A, B;
A.lengthinit(initial.map!(c => initialc == '#').lengtharray);
B.length = initial.length;
 
foreach (immutable _; 0 .. nGenerations) {
// auto A = BitArray(initial.map!(c => c == '#'));
//A.map!(b => b ? '#' : '_').writeln;
foreach (immutable i, immutable c; initial)
A[i] = c == '#';
 
foreach (immutable _; 0 .. numGenerations) {
//A.map!(b => b ? '#' : '_').weiteln;
//foreach (immutable i, immutable b; A) {
foreach (immutable i; 1 .. A.length - 1) {
"_#"[A[i]].write;
immutable val = (cast(uint)(A[i - 1]) << 2) |
(cast(uint)(A[i]) << 1) |
cast( uint)(A[i + 1]);
B[i] = val == 3 || val == 5 || val == 6;
}
Line 980 ⟶ 2,026:
A.swap(B);
}
}</langsyntaxhighlight>
The output is the same as the second version.
 
=={{header|Dëjà VuDWScript}}==
<syntaxhighlight lang="delphi">const ngenerations = 10;
const table = [0, 0, 0, 1, 0, 1, 1, 0];
 
var a := [0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0];
var b := a;
 
var i, j : Integer;
for i := 1 to ngenerations do begin
for j := a.low+1 to a.high-1 do begin
if a[j] = 0 then
Print('_')
else Print('#');
var val := (a[j-1] shl 2) or (a[j] shl 1) or a[j+1];
b[j] := table[val];
end;
var tmp := a;
a := b;
b := tmp;
PrintLn('');
end;
</syntaxhighlight>
{{out}}
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________</pre>
 
=={{header|Déjà Vu}}==
 
<langsyntaxhighlight lang="dejavu">new-state size:
0 ]
repeat size:
Line 1,020 ⟶ 2,100:
return print-state drop
 
run 60</langsyntaxhighlight>
{{out}}
<pre>001110011010110111001111110111011111010011000001010111111100
Line 1,032 ⟶ 2,112:
000000000000000110000000000000000001100011000000000000000000</pre>
 
=={{header|DWScript}}==
<lang delphi>const ngenerations = 10;
const table = [0, 0, 0, 1, 0, 1, 1, 0];
 
=={{header|Delphi}}==
var a := [0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0];
{{works with|Delphi|6.0}}
var b := a;
{{libheader|SysUtils,StdCtrls}}
 
 
<syntaxhighlight lang="Delphi">
type TGame = string[20];
type TPattern = string[3];
 
function GetSubPattern(Game: TGame; Inx: integer): TPattern;
var i, j : Integer;
{Get the pattern of three cells adjacent to Inx}
for i := 1 to ngenerations do begin
var I: integer;
for j := a.low+1 to a.high-1 do begin
begin
if a[j] = 0 then
Result:='';
Print('_')
{Cells off the ends of the array are consider empty}
else Print('#');
for I:=Inx-1 to Inx+1 do
var val := (a[j-1] shl 2) or (a[j] shl 1) or a[j+1];
if (I<1) or (I>Length(Game)) then Result:=Result+' '
b[j] := table[val];
else Result:=Result+Game[I];
end;
var tmp := a;
a := b;
b := tmp;
PrintLn('');
end;
</lang>
Output:
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________</pre>
 
function GetNewValue(P: TPattern): char;
{Calculate the new value for a cell based}
{the pattern of neighboring cells}
begin
if P=' ' then Result:=' ' { No change}
else if P=' #' then Result:=' ' { No change}
else if P=' # ' then Result:=' ' { Dies without enough neighbours}
else if P=' ##' then Result:='#' { Needs one neighbour to survive}
else if P='# ' then Result:=' ' { No change}
else if P='# #' then Result:='#' { Two neighbours giving birth}
else if P='## ' then Result:='#' { Needs one neighbour to survive}
else if P='###' then Result:=' '; { Starved to death.}
end;
 
 
procedure CellularlAutoGame(Memo: TMemo);
{Iterate through steps of evolution of cellular automaton}
var GameArray,NextArray: TGame;
var P: string [3];
var I,G: integer;
begin
{Start arrangement}
GameArray:=' ### ## # # # # # ';
for G:=1 to 10 do
begin
{Display current game situation}
Memo.Lines.Add(GameArray);
{Evolve each cell in the array}
for I:=1 to Length(GameArray) do
begin
P:=GetSubPattern(GameArray,I);
NextArray[I]:=GetNewValue(P);
end;
GameArray:=NextArray;
end;
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
### ## # # # # #
# ##### # # #
## ## # #
## ### #
## # ##
## ###
## # #
## #
##
##
Elapsed Time: 9.784 ms.
</pre>
 
=={{header|E}}==
 
<langsyntaxhighlight lang="e">def step(state, rule) {
var result := state(0, 1) # fixed left cell
for i in 1..(state.size() - 2) {
Line 1,086 ⟶ 2,206:
}
return state
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="e">def rosettaRule := [
" " => " ",
" #" => " ",
Line 1,110 ⟶ 2,230:
8 | ##
9 | ##
# value: " ## "</langsyntaxhighlight>
 
=={{header|EasyLang}}==
<syntaxhighlight lang=easylang>
map[] = [ 0 0 0 1 0 1 1 0 ]
cell[] = [ 0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 ]
len celln[] len cell[]
proc evolve . .
for i = 2 to len cell[] - 1
ind = cell[i - 1] + 2 * cell[i] + 4 * cell[i + 1] + 1
celln[i] = map[ind]
.
swap celln[] cell[]
.
proc show . .
for v in cell[]
if v = 1
write "#"
else
write "."
.
.
print ""
.
show
for i to 9
evolve
show
.
</syntaxhighlight>
{{out}}
<pre>
.###.##.#.#.#.#..#..
.#.#####.#.#.#......
..##...##.#.#.......
..##...###.#........
..##...#.##.........
..##....###.........
..##....#.#.........
..##.....#..........
..##................
..##................
</pre>
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
class
APPLICATION
 
create
make
 
feature
 
make
-- First 10 states of the cellular automata.
local
r: RANDOM
automata: STRING
do
create r.make
create automata.make_empty
across
1 |..| 10 as c
loop
if r.double_item < 0.5 then
automata.append ("0")
else
automata.append ("1")
end
r.forth
end
across
1 |..| 10 as c
loop
io.put_string (automata + "%N")
automata := update (automata)
end
end
 
update (s: STRING): STRING
-- Next state of the cellular automata 's'.
require
enough_states: s.count > 1
local
i: INTEGER
do
create Result.make_empty
-- Dealing with the left border.
if s [1] = '1' and s [2] = '1' then
Result.append ("1")
else
Result.append ("0")
end
-- Dealing with the middle cells.
from
i := 2
until
i = s.count
loop
if (s [i] = '0' and (s [i - 1] = '0' or (s [i - 1] = '1' and s [i + 1] = '0'))) or ((s [i] = '1') and ((s [i - 1] = '1' and s [i + 1] = '1') or (s [i - 1] = '0' and s [i + 1] = '0'))) then
Result.append ("0")
else
Result.append ("1")
end
i := i + 1
end
-- Dealing with the right border.
if s [s.count] = '1' and s [s.count - 1] = '1' then
Result.append ("1")
else
Result.append ("0")
end
ensure
has_same_length: s.count = Result.count
end
 
end
</syntaxhighlight>
{{out}}
<pre>
1011101110
0110111010
0111101100
0100111100
0000100100
0000000000
0000000000
0000000000
0000000000
0000000000
</pre>
 
=={{header|Elixir}}==
{{trans|Ruby}}
<syntaxhighlight lang="elixir">defmodule RC do
def run(list, gen \\ 0) do
print(list, gen)
next = evolve(list)
if next == list, do: print(next, gen+1), else: run(next, gen+1)
end
defp evolve(list), do: evolve(Enum.concat([[0], list, [0]]), [])
defp evolve([a,b,c], next), do: Enum.reverse([life(a,b,c) | next])
defp evolve([a,b,c|rest], next), do: evolve([b,c|rest], [life(a,b,c) | next])
defp life(a,b,c), do: (if a+b+c == 2, do: 1, else: 0)
defp print(list, gen) do
str = "Generation #{gen}: "
IO.puts Enum.reduce(list, str, fn x,s -> s <> if x==0, do: ".", else: "#" end)
end
end
 
RC.run([0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0])</syntaxhighlight>
 
{{out}}
<pre>
Generation 0: .###.##.#.#.#.#..#..
Generation 1: .#.#####.#.#.#......
Generation 2: ..##...##.#.#.......
Generation 3: ..##...###.#........
Generation 4: ..##...#.##.........
Generation 5: ..##....###.........
Generation 6: ..##....#.#.........
Generation 7: ..##.....#..........
Generation 8: ..##................
Generation 9: ..##................
</pre>
 
=={{header|Elm}}==
<syntaxhighlight lang="elm">import Maybe exposing (withDefault)
import List exposing (length, tail, reverse, concat, head, append, map3)
import Html exposing (Html, div, h1, text)
import String exposing (join)
import Svg exposing (svg)
import Svg.Attributes exposing (version, width, height, viewBox,cx,cy, fill, r)
import Html.App exposing (program)
import Random exposing (step, initialSeed, bool, list)
import Matrix exposing (fromList, mapWithLocation, flatten) -- chendrix/elm-matrix
import Time exposing (Time, second, every)
 
type alias Model = { history : List (List Bool)
, cols : Int
, rows : Int
}
 
view : Model -> Html Msg
view model =
let
circleInBox (row,col) value =
if value
then [ Svg.circle [ r "0.3"
, fill ("purple")
, cx (toString (toFloat col + 0.5))
, cy (toString (toFloat row + 0.5))
]
[]
]
else []
 
showHistory model =
model.history
|> reverse
|> fromList
|> mapWithLocation circleInBox
|> flatten
|> concat
in
div []
[ h1 [] [text "One Dimensional Cellular Automata"]
, svg [ version "1.1"
, width "700"
, height "700"
, viewBox (join " "
[ 0 |> toString
, 0 |> toString
, model.cols |> toString
, model.rows |> toString
]
)
]
(showHistory model)
]
 
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
if length model.history == model.rows
then (model, Cmd.none)
else
let s1 = model.history |> head |> withDefault []
s0 = False :: s1
s2 = append (tail s1 |> withDefault []) [False]
gen d0 d1 d2 =
case (d0,d1,d2) of
(False, True, True) -> True
( True, False, True) -> True
( True, True, False) -> True
_ -> False
 
updatedHistory = map3 gen s0 s1 s2 :: model.history
updatedModel = {model | history = updatedHistory}
in (updatedModel, Cmd.none)
 
init : Int -> (Model, Cmd Msg)
init n =
let gen1 = fst (step (list n bool) (initialSeed 34))
in ({ history = [gen1], rows = n, cols= n }, Cmd.none)
 
type Msg = Tick Time
 
subscriptions model = every (0.2 * second) Tick
 
main = program
{ init = init 40
, view = view
, update = update
, subscriptions = subscriptions
}</syntaxhighlight>
 
Link to live demo: https://dc25.github.io/oneDimensionalCellularAutomataElm/
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">
-module(ca).
-compile(export_all).
Line 1,161 ⟶ 2,545:
next([1,1,1|T],Acc) ->
next([1,1|T],[0|Acc]).
</syntaxhighlight>
</lang>
Example execution:
<langsyntaxhighlight lang="erlang">
44> ca:run(9,[0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0]).
0: __###_##_#_#_#_#__#___
Line 1,175 ⟶ 2,559:
8: ___##_________________
9: ___##_________________
</syntaxhighlight>
</lang>
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
PROGRAM ONEDIM_AUTOMATA
 
! for rosettacode.org
!
 
!VAR I,J,N,W,K
 
!$DYNAMIC
DIM X[0],X2[0]
 
BEGIN
 
DATA(20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0)
 
PRINT(CHR$(12);)
N=20 ! number of generation required
READ(W)
!$DIM X[W+1],X2[W+1]
FOR I=1 TO W DO
READ(X[I])
END FOR
FOR K=1 TO N DO
PRINT("Generation";K;TAB(16);)
FOR J=1 TO W DO
IF X[J]=1 THEN PRINT("#";) ELSE PRINT("_";) END IF
IF X[J-1]+X[J]+X[J+1]=2 THEN X2[J]=1 ELSE X2[J]=0 END IF
END FOR
PRINT
FOR J=1 TO W DO
X[J]=X2[J]
END FOR
END FOR
END PROGRAM
</syntaxhighlight>
{{out}}
<pre>
Generation 1 _###_##_#_#_#_#__#__
Generation 2 _#_#####_#_#_#______
Generation 3 __##___##_#_#_______
Generation 4 __##___###_#________
Generation 5 __##___#_##_________
Generation 6 __##____###_________
Generation 7 __##____#_#_________
Generation 8 __##_____#__________
Generation 9 __##________________
Generation 10 __##________________
Generation 11 __##________________
Generation 12 __##________________
Generation 13 __##________________
Generation 14 __##________________
Generation 15 __##________________
Generation 16 __##________________
Generation 17 __##________________
Generation 18 __##________________
Generation 19 __##________________
Generation 20 __##________________
</pre>
 
=={{header|Euphoria}}==
<langsyntaxhighlight lang="euphoria">include machine.e
 
function rules(integer tri)
Line 1,222 ⟶ 2,667:
 
printf(1,"Generation %d: ",n)
print_gen(gen)</langsyntaxhighlight>
 
{{out}}
Output:
Generation 0: ####__#_###_#_#_#_#_##___##_##__
Generation 1: ___#___##_##_#_#_#_###___#####__
Line 1,236 ⟶ 2,681:
 
=={{header|Factor}}==
<langsyntaxhighlight lang="factor">USING: bit-arrays io kernel locals math sequences ;
IN: cellular
 
Line 1,257 ⟶ 2,702:
10 [ dup print-cellular step ] times print-cellular ;
MAIN: main-cellular
</syntaxhighlight>
</lang>
<pre>( scratchpad ) "cellular" run
_###_##_#_#_#_#__#__
Line 1,272 ⟶ 2,717:
 
=={{header|Fantom}}==
<langsyntaxhighlight lang="fantom">
class Automaton
{
Line 1,303 ⟶ 2,748:
}
}
</syntaxhighlight>
</lang>
 
=={{header|FOCAL}}==
<syntaxhighlight lang="focal">1.1 S OLD(2)=1; S OLD(3)=1; S OLD(4)=1; S OLD(6)=1; S OLD(7)=1
1.2 S OLD(9)=1; S OLD(11)=1; S OLD(13)=1; S OLD(15)=1; S OLD(18)=1
1.3 F N=1,10; D 2
1.4 Q
 
2.1 F X=1,20; D 3
2.2 F X=1,20; D 6
2.3 F X=1,20; S OLD(X)=NEW(X)
2.4 T !
 
3.1 I (OLD(X-1)+OLD(X)+OLD(X+1)-2)4.1,5.1,4.1
 
4.1 S NEW(X)=0
 
5.1 S NEW(X)=1
 
6.1 I (-OLD(X))7.1,8.1,8.1
 
7.1 T "#"
 
8.1 T "."</syntaxhighlight>
{{output}}
<pre>
.###.##.#.#.#.#..#..
.#.#####.#.#.#......
..##...##.#.#.......
..##...###.#........
..##...#.##.........
..##....###.........
..##....#.#.........
..##.....#..........
..##................
..##................
</pre>
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: init ( bits count -- )
0 do dup 1 and c, 2/ loop drop ;
 
Line 1,330 ⟶ 2,811:
.state 1 do gen .state loop ;
 
10 life1d</langsyntaxhighlight>
 
ouput
<syntaxhighlight lang="text">
### ## # # # # #
# ##### # # #
## ## # #
## ### #
## # ##
## ###
## # #
## #
##
## ok
</syntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">PROGRAM LIFE_1D
IMPLICIT NONE
Line 1,383 ⟶ 2,878:
END SUBROUTINE Drawgen
END PROGRAM LIFE_1D</langsyntaxhighlight>
{{out}}
Output
<pre>
Generation 0: _###_##_#_#_#_#__#__
Generation 1: _#_#####_#_#_#______
Line 1,394 ⟶ 2,890:
Generation 7: __##_____#__________
Generation 8: __##________________
Generation 9: __##________________</pre>
 
=={{header|Go}}==
===Sequential===
<lang go>package main
<syntaxhighlight lang="go">package main
 
import "fmt"
 
const (
const start = "_###_##_#_#_#_#__#__"
start = "_###_##_#_#_#_#__#__"
offLeft = '_'
offRight = '_'
dead = '_'
)
 
func main() {
g0 := []bytefmt.Println(start)
g1g := []bytenewGenerator(start, offLeft, offRight, dead)
for i := 0; i < 10; i++ {
fmt.Println(string(g0))
fmt.Println(g())
}
}
 
func newGenerator(start string, offLeft, offRight, dead byte) func() string {
g0 := string(offLeft) + start + string(offRight)
g1 := []byte(g0)
last := len(g0) - 1
forreturn gfunc() := 0; g < 10; g++string {
for i := 1; i < last; i++ {
switch l := g0[i-1]; {
case g0[i-1]l != g0[i+1]:
g1[i] = g0[i]
case g0[i] == '_'dead:
g1[i] = g0[i-1]l
default:
g1[i] = '_'dead
}
}
fmt.Println(g0 = string(g1))
copy(g0,return g1)g0[1:last]
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
_###_##_#_#_#_#__#__
Line 1,436 ⟶ 2,946:
__##________________
</pre>
 
===Concurrent===
Computations run on each cell concurrently.
Separate read and write phases.
Single array of cells.
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"sync"
)
 
const (
start = "_###_##_#_#_#_#__#__"
offLeft = '_'
offRight = '_'
dead = '_'
)
 
func main() {
fmt.Println(start)
a := make([]byte, len(start)+2)
a[0] = offLeft
copy(a[1:], start)
a[len(a)-1] = offRight
var read, write sync.WaitGroup
read.Add(len(start) + 1)
for i := 1; i <= len(start); i++ {
go cell(a[i-1:i+2], &read, &write)
}
for i := 0; i < 10; i++ {
write.Add(len(start) + 1)
read.Done()
read.Wait()
read.Add(len(start) + 1)
write.Done()
write.Wait()
fmt.Println(string(a[1 : len(a)-1]))
}
}
 
func cell(kernel []byte, read, write *sync.WaitGroup) {
var next byte
for {
l, v, r := kernel[0], kernel[1], kernel[2]
read.Done()
switch {
case l != r:
next = v
case v == dead:
next = l
default:
next = dead
}
read.Wait()
kernel[1] = next
write.Done()
write.Wait()
}
}</syntaxhighlight>
Output is same as sequential version.
 
=={{header|Groovy}}==
Solution:
<langsyntaxhighlight lang="groovy">def life1D = { self ->
def right = self[1..-1] + [false]
def left = [false] + self[0..-2]
[left, self, right].transpose().collect { hood -> hood.count { it } == 2 }
}</langsyntaxhighlight>
 
Test:
<langsyntaxhighlight lang="groovy">def cells = ('_###_##_#_#_#_#__#__' as List).collect { it == '#' }
println "Generation 0: ${cells.collect { g -> g ? '#' : '_' }.join()}"
(1..9).each {
cells = life1D(cells)
println "Generation ${it}: ${cells.collect { g -> g ? '#' : '_' }.join()}"
}</langsyntaxhighlight>
 
{{out}}
Output:
<pre>Generation 0: _###_##_#_#_#_#__#__
Generation 1: _#_#####_#_#_#______
Line 1,466 ⟶ 3,037:
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">moduleimport Life1DData.List where(unfoldr)
import System.Random (newStdGen, randomRs)
 
bnd :: String -> Char
import Data.List
bnd "_##" = '#'
import System.Random
bnd "#_#" = '#'
import Control.Monad
bnd "##_" = '#'
import Control.Arrow
bnd _ = '_'
 
bndnxt :: [Char]String -> CharString
nxt = unfoldr go . ('_' :) . (<> "_")
bnd bs =
where
case bs of
go [_, "_##"] ->= '#'Nothing
go xs = Just "#_#"(bnd ->$ '#'take 3 xs, drop 1 xs)
"##_" -> '#'
_ -> '_'
 
lahmahgaan :: String -> [String]
donxt xs = unfoldr(\xs -> case xs of [_,_] -> Nothing ;
lahmahgaan xs =
_ -> Just (bnd $ take 3 xs, drop 1 xs)) $ '_':xs++"_"
init
. until
((==) . last <*> last . init)
((<>) <*> pure . nxt . last)
$ [xs, nxt xs]
 
main :: IO ()
lahmahgaan xs = init.until (liftM2 (==) last (last. init)) (ap (++)(return. donxt. last)) $ [xs, donxt xs]
main =
 
newStdGen
main = do
>>= ( mapM_ putStrLn . lahmahgaan
g <- newStdGen
let oersoep = . map ("_#" !!). take 36 $ randomRs(0,1) g
. take 36
mapM_ print . lahmahgaan $ oersoep</lang>
. randomRs (0, 1)
Some output:
)</syntaxhighlight>
<lang haskell>*Life1D> mapM_ print . lahmahgaan $ "_###_##_#_#_#_#__#__"
{{Out}}
"_###_##_#_#_#_#__#__"
For example:
"_#_#####_#_#_#______"
"<pre>_##_#_#__#_#____#_#_###_#_______"######_#_#__##
_###_#____#_#_#_##_###_____##_#___##
"__##___###_#________"
_#_##______#_#_#####_#_____###____##
"__##___#_##_________"
__###_______#_##___##______#_#____##
"__##____###_________"
__#_#________###___##_______#_____##
"__##____#_#_________"
___#_________#_#___##_____________##
"__##_____#__________"
______________#____##_____________##
"__##________________"
___________________##_____________##</pre>
*Life1D> main
"__##_##__#____###__#__#_______#_#_##"
"__#####_______#_#______________#_###"
"__#___#________#________________##_#"
"________________________________###_"
"________________________________#_#_"
"_________________________________#__"
"____________________________________"</lang>
 
=={{header|Icon}} and {{header|Unicon}}==
 
<langsyntaxhighlight lang="icon">
# One dimensional Cellular automaton
record Automaton(size, cells)
Line 1,550 ⟶ 3,118:
}
end
</syntaxhighlight>
</lang>
 
An alternative approach is to represent the automaton as a string. The following
The following solution takes advantage of the implicit type coercions between string and numeric
between string and numeric values in Icon and Unicon. It also surrounds the automaton with a border of 'dead'
(alwaysIt 0)also cells to eliminatesurrounds the needautomaton towith speciala caseborder theof first'dead' and(always last0) cells in
theto automaton. Althougheliminate the mainneed procedureto displaysspecial up tocase the first 10and last cells generations,
in the automaton.
the evolve procedure fails if a new generation is unchanged from the previous, stopping
Although the main procedure displays up to the first 10 generations,
the generation cycle early.
the evolve procedure fails if a new generation is unchanged from the previous, stopping the generation cycle early.
 
<langsyntaxhighlight lang="unicon">procedure main(A)
A := if *A = 0 then ["01110110101010100100"]
CA := show("0"||A[1]||"0") # add always dead border cells
Line 1,575 ⟶ 3,144:
every newCA[i := 2 to (*CA-1)] := (CA[i-1]+CA[i]+CA[i+1] = 2, "1")
return CA ~== newCA # fail if no change
end</langsyntaxhighlight>
 
{{out|A couple of sample runs:}}
<pre>->odca
01110110101010100100
Line 1,594 ⟶ 3,163:
00110000
-></pre>
 
=={{Header|Insitux}}==
 
<syntaxhighlight lang="insitux">
(function next cells
(... str
(map (comp str (count ["#"]) (= 2) #(% "#" "_"))
(str "_" cells)
cells
(str (skip 1 cells) "_"))))
 
(function generate n cells
(join "\n" (reductions next cells (range n))))
</syntaxhighlight>
 
{{out}}
 
Invoking <code>(generate 9 "_###_##_#_#_#_#__#__")</code>
 
<pre>
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________
</pre>
 
=={{header|J}}==
<langsyntaxhighlight lang="j">life1d=: '_#'{~ (2 = 3+/\ 0,],0:)^:a:</langsyntaxhighlight>
 
Example use:
{{out|Example use}}
<lang j> life1d ? 20 # 2
<syntaxhighlight lang="j"> life1d ? 20 # 2
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
Line 1,607 ⟶ 3,208:
__##____#_#_________
__##_____#__________
__##________________</langsyntaxhighlight>
 
Alternative implementation:
 
<langsyntaxhighlight lang="j">Rule=:2 :0 NB. , m: number of generations, n: rule number
'_#'{~ (3 ((|.n#:~8#2) {~ #.)\ 0,],0:)^:(i.m)
)</langsyntaxhighlight>
 
{{out|Example use:}}
<syntaxhighlight lang="j"> 9 Rule 104 '#'='_###_##_#_#_#_#__#__'
 
<lang j> 9 Rule 104 '#'='_###_##_#_#_#_#__#__'
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
Line 1,626 ⟶ 3,226:
__##____#_#_________
__##_____#__________
__##________________</langsyntaxhighlight>
 
 
=={{header|Java}}==
This example requires a starting generation of at least length two (which is what you need for anything interesting anyway).
(which is what you need for anything interesting anyway).
<lang java>public class Life{
<syntaxhighlight lang="java">public class Life{
public static void main(String[] args) throws Exception{
String start= "_###_##_#_#_#_#__#__";
Line 1,672 ⟶ 3,272:
return ans;
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>Generation 0: _###_##_#_#_#_#__#__
Generation 1: _#_#####_#_#_#______
Line 1,685 ⟶ 3,285:
Generation 9: __##________________</pre>
{{trans|C}}
In this version, <code>b</code> is replaced by a <code>backup</code> which is local to the <code>evolve</code> method, and the <code>evolve</code> method returns a boolean.
which is local to the <code>evolve</code> method,
<lang java>public class Life{
and the <code>evolve</code> method returns a boolean.
<syntaxhighlight lang="java">public class Life{
private static char[] trans = "___#_##_".toCharArray();
 
Line 1,716 ⟶ 3,318:
}while(evolve(c));
}
}</langsyntaxhighlight>
{{out}}
Output:
<pre>###_##_#_#_#_#__#__
#_#####_#_#_#______
Line 1,729 ⟶ 3,331:
 
=={{header|JavaScript}}==
The example below expects an array of 1s or 0s, as in the example. It also adds dead cells to both ends, which aren't included in the returned next generation.
It also adds dead cells to both ends,
which aren't included in the returned next generation.
 
state[i-1] refers to the new cell in question, (old[i] == 1) checks if the old cell was alive.
(old[i] == 1) checks if the old cell was alive.
<lang javascript>function caStep(old) {
<syntaxhighlight lang="javascript">function caStep(old) {
var old = [0].concat(old, [0]); // Surround with dead cells.
var state = []; // The new state.
Line 1,744 ⟶ 3,349:
}
return state;
}</langsyntaxhighlight>
 
{{out|Example usage:}}
<langsyntaxhighlight lang="javascript">alert(caStep([0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0]));</langsyntaxhighlight>
shows an alert with "0,1,0,1,1,1,1,1,0,1,0,1,0,1,0,0,0,0,0,0".
 
=={{header|jq}}==
The main point of interest in the following is perhaps the way the built-in function "recurse" is used to continue the simulation until quiescence.
<syntaxhighlight lang="jq"># The 1-d cellular automaton:
def next:
# Conveniently, jq treats null as 0 when it comes to addition
# so there is no need to fiddle with the boundaries
. as $old
| reduce range(0; length) as $i
([];
($old[$i-1] + $old[$i+1]) as $s
| if $s == 0 then .[$i] = 0
elif $s == 1 then .[$i] = (if $old[$i] == 1 then 1 else 0 end)
else .[$i] = (if $old[$i] == 1 then 0 else 1 end)
end);
 
 
# pretty-print an array:
def pp: reduce .[] as $i (""; . + (if $i == 0 then " " else "*" end));
 
# continue until quiescence:
def go: recurse(. as $prev | next | if . == $prev then empty else . end) | pp;
 
# Example:
[0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0] | go</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">$ jq -c -r -n -f One-dimensional_cellular_automata.jq
*** ** * * * * *
* ***** * * *
** ** * *
** *** *
** * **
** ***
** * *
** *
**</syntaxhighlight>
 
=={{header|Julia}}==
=== Julia: Implementation as a function accepting a Vector of Bool ===
<syntaxhighlight lang="julia">
automaton(g::Vector{Bool}) =
for i ∈ 0:9
println(join(alive ? '#' : '_' for alive ∈ g))
g = ([false; g[1:end-1]] .+ g .+ [g[2:end]; false]) .== 2
end
automaton([c == '#' for c ∈ "_###_##_#_#_#_#__#__"])
</syntaxhighlight>
=== Julia: Implementation as an iterable struct ===
<syntaxhighlight lang="julia">
struct Automaton g₀::Vector{Bool} end
 
Base.iterate(a::Automaton, g = a.g₀) =
g, ([false; g[1:end-1]] .+ g .+ [g[2:end]; false]) .== 2
 
Base.show(io::IO, a::Automaton) = for g in Iterators.take(a, 10)
println(io, join(alive ? '#' : '_' for alive ∈ g)) end
 
Automaton([c == '#' for c ∈ "_###_##_#_#_#_#__#__"])
</syntaxhighlight>
{{out}}
<pre>
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________
</pre>
 
=={{header|K}}==
<langsyntaxhighlight Klang="k">f:{2=+/(0,x,0)@(!#x)+/:!3}</langsyntaxhighlight>
 
{{out|Example usage:}}
<langsyntaxhighlight Klang="k"> `0:"_X"@f\0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0
_XXX_XX_X_X_X_X__X__
_X_XXXXX_X_X_X______
Line 1,765 ⟶ 3,442:
__XX_____X__________
__XX________________
</syntaxhighlight>
</lang>
 
=={{header|Liberty BASICKotlin}}==
{{trans|C}}
<lang lb>' [RC] 'One-dimensional cellular automata'
<syntaxhighlight lang="scala">// version 1.1.4-3
 
val trans = "___#_##_"
 
fun v(cell: StringBuilder, i: Int) = if (cell[i] != '_') 1 else 0
global rule$, state$
 
fun evolve(cell: StringBuilder, backup: StringBuilder): Boolean {
rule$ ="00010110" ' Rule 22 decimal
val len = cell.length - 2
var diff = 0
for (i in 1 until len) {
/* use left, self, right as binary number bits for table index */
backup[i] = trans[v(cell, i - 1) * 4 + v(cell, i) * 2 + v(cell, i + 1)]
diff += if (backup[i] != cell[i]) 1 else 0
}
cell.setLength(0)
cell.append(backup)
return diff != 0
}
 
fun main(args: Array<String>) {
state$ ="0011101101010101001000"
val c = StringBuilder("_###_##_#_#_#_#__#__")
val b = StringBuilder("____________________")
do {
println(c.substring(1))
}
while (evolve(c,b))
}</syntaxhighlight>
 
{{out}}
for j =1 to 20
<pre>
oldState$ =state$
###_##_#_#_#_#__#__
state$ ="0"
#_#####_#_#_#______
for k =2 to 32
_##___##_#_#_______
NHood$ =mid$( oldState$, k -1, 3) ' pick 3 char neighbourhood and turn binary string to decimal
_##___###_#________
vNHood =0
_##___#_##_________
for kk =3 to 1 step -1
_##____###_________
vNHood =vNHood +val( mid$( NHood$, kk, 1)) *2^( 3 -kk)
_##____#_#_________
next kk
_##_____#__________
' .... & use it to index into rule$ to find appropriate new value
_##________________
state$ =state$ +mid$( rule$, vNHood +1, 1)
</pre>
next k
 
print state$
next j
 
end</lang>
 
=={{header|Locomotive Basic}}==
 
<lang locobasic>10 MODE 1:n=10:READ w:DIM x(w+1),x2(w+1):FOR i=1 to w:READ x(i):NEXT
20 FOR k=1 TO n
30 FOR j=1 TO w
40 IF x(j) THEN PRINT "#"; ELSE PRINT "_";
50 IF x(j-1)+x(j)+x(j+1)=2 THEN x2(j)=1 ELSE x2(j)=0
60 NEXT:PRINT
70 FOR j=1 TO w:x(j)=x2(j):NEXT
80 NEXT
90 DATA 20,0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0</lang>
 
Output:
 
[[File:Cellular automaton locomotive basic.png]]
 
=={{header|Logo}}==
{{works with|UCB Logo}}
<langsyntaxhighlight lang="logo">make "cell_list [0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0]
make "generations 9
 
Line 1,850 ⟶ 3,526:
end
 
CA_1D :cell_list :generations</langsyntaxhighlight>
{{out}}
Sample Output:
<pre>
Generation 0: _###_##_#_#_#_#__#__
Line 1,864 ⟶ 3,540:
Generation 9: __##________________
</pre>
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">num_iterations = 9
f = { 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 }
 
Line 1,896 ⟶ 3,573:
 
Output( f, l )
end </langsyntaxhighlight>
{{out}}
<pre>0: _###_##_#_#_#_#__#__
1: _#_#####_#_#_#______
Line 1,909 ⟶ 3,587:
 
=={{header|M4}}==
<langsyntaxhighlight M4lang="m4">divert(-1)
define(`set',`define(`$1[$2]',`$3')')
define(`get',`defn(`$1[$2]')')
Line 1,944 ⟶ 3,622:
for(`j',1,10,
`show(x)`'evolve(`x',`y')`'swap(`x',x,`y')
')`'show(x)</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0
Line 1,961 ⟶ 3,639:
</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Built-in function:
<langsyntaxhighlight Mathematicalang="mathematica">CellularAutomaton[{{0,0,_}->0,{0,1,0}->0,{0,1,1}->1,{1,0,0}->0,{1,0,1}->1,{1,1,0}->1,{1,1,1}->0},{{1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1},0},12]
Print @@@ (% /. {1 -> "#", 0 -> "."});</langsyntaxhighlight>
For succinctness, an integral rule can be used:
gives back:
<syntaxhighlight lang="mathematica">CellularAutomaton[2^^01101000 (* == 104 *), {{1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1}, 0}, 12];</syntaxhighlight>
<lang Mathematica>###.##.#.#.#.#..#
{{out}}
<syntaxhighlight lang="mathematica">###.##.#.#.#.#..#
#.#####.#.#.#....
.##...##.#.#.....
Line 1,978 ⟶ 3,658:
.##..............
.##..............
.##..............</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
<langsyntaxhighlight MATLABlang="matlab">function one_dim_cell_automata(v,n)
V='_#';
while n>=0;
Line 1,989 ⟶ 3,669:
v = v(3:end)==2;
end;
end</langsyntaxhighlight>
{{out}}
<pre>octave:27> one_dim_cell_automata('01110110101010100100'=='1',20);
_###_##_#_#_#_#__#__
Line 2,003 ⟶ 3,684:
__##________________
...</pre>
 
 
=={{header|Modula-3}}==
{{trans|Ada}}
 
Modula-3 provides a module <code>Word</code> for doing bitwise operations, but it segfaults when trying to use <code>BOOLEAN</code> types, so we use <code>INTEGER</code> instead.
but it segfaults when trying to use <code>BOOLEAN</code> types,
<lang modula3>MODULE Cell EXPORTS Main;
so we use <code>INTEGER</code> instead.
<syntaxhighlight lang="modula3">MODULE Cell EXPORTS Main;
 
IMPORT IO, Fmt, Word;
Line 2,051 ⟶ 3,733:
Step(culture);
END;
END Cell.</langsyntaxhighlight>
{{out}}
Output:
<pre>
Generation 0 _###_##_#_#_#_#__#__
Line 2,065 ⟶ 3,747:
Generation 9 __##________________
</pre>
 
=={{header|MontiLang}}==
<syntaxhighlight lang="montilang">30 VAR length .
35 VAR height .
FOR length 0 ENDFOR 1 0 ARR VAR list .
length 1 - VAR topLen .
FOR topLen 0 ENDFOR 1 ARR VAR topLst .
 
DEF getNeighbors
1 - VAR tempIndex .
GET tempIndex SWAP
tempIndex 1 + VAR tempIndex .
GET tempIndex SWAP
tempIndex 1 + VAR tempIndex .
GET tempIndex SWAP .
FOR 3 TOSTR ROT ENDFOR
FOR 2 SWAP + ENDFOR
ENDDEF
 
DEF printArr
LEN 1 - VAR stLen .
0 VAR j .
FOR stLen
GET j
TOSTR OUT .
j 1 + VAR j .
ENDFOR
|| PRINT .
ENDDEF
 
FOR height
FOR length 0 ENDFOR ARR VAR next .
1 VAR i .
FOR length
list i getNeighbors VAR last .
i 1 - VAR ind .
last |111| ==
IF : .
next 0 INSERT ind
ENDIF
 
last |110| ==
IF : .
next 1 INSERT ind
ENDIF
 
last |101| ==
IF : .
next 1 INSERT ind
ENDIF
 
last |100| ==
IF : .
next 0 INSERT ind
ENDIF
 
last |011| ==
IF : .
next 1 INSERT ind
ENDIF
 
last |010| ==
IF : .
next 1 INSERT ind
ENDIF
 
last |001| ==
IF : .
next 1 INSERT ind
ENDIF
 
last |000| ==
IF : .
next 0 INSERT ind
ENDIF
clear
i 1 + VAR i .
ENDFOR
next printArr .
next 0 ADD APPEND . VAR list .
ENDFOR</syntaxhighlight>
 
=={{header|Nial}}==
(life.nial)
<langsyntaxhighlight lang="nial">% we need a way to write a values and pass the same back
wi is rest link [write, pass]
% calculate the neighbors by rotating the array left and right and joining them
Line 2,077 ⟶ 3,840:
nextgen is each igen neighbors
% 42
life is fork [ > [sum pass, 0 first], life nextgen wi, pass ]</langsyntaxhighlight>
 
Using it
{{out|Using it}}
<lang nial>|loaddefs 'life.nial'
<syntaxhighlight lang="nial">|loaddefs 'life.nial'
|I := [0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0]
|life I</langsyntaxhighlight>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import random
 
=={{header|Nimrod}}==
<lang Nimrod>
import math
randomize()
 
type
TBoolArrayBoolArray = array[0..30, bool] # an array that is indexed with 0..10
TSymbolsSymbols = tuple[on: char ,= off:array[bool, char]
 
 
proc neighbours(map: BoolArray, i: int): int =
if i > 0: inc(result, int(map[i - 1]))
if i + 1 < len(map): inc(result, int(map[i + 1]))
 
proc print(map: BoolArray, symbols: Symbols) =
for i in map: write(stdout, symbols[i])
write(stdout, "\l")
proc randomMap: BoolArray =
randomize()
for i in mitems(result): i = sample([true, false])
 
 
const
num_turns = 20
symbols symbols:TSymbols = (['#_', '_#')]
 
T = true
proc `==` (x:TBoolArray,y:TBoolArray): bool =
F = false
if len(x) != len(y):
return False
for i in 0..(len(x)-1):
if x[i] != y[i]:
return False
return True
 
var map =
proc count_neighbours(map:TBoolArray , tile:int):int =
[F, T, T, T, F, T, T, F, T, F, T, F, T, F, T,
result = 0
F, F, T, F, F, F, F, F, F, F, F, F, F, F, F]
if tile != len(map)-1 and map[tile+1]:
result += 1
if tile != 0 and map[tile-1]:
result += 1
 
# map = randomMap() # uncomment for random start
proc print_map(map:TBoolArray, symbols:TSymbols) =
for i in map:
if i:
write(stdout,symbols[0])
else:
write(stdout,symbols[1])
write(stdout,"\n")
 
print(map, symbols)
proc random_map(): TBoolArray =
var map = [False,False,False,False,False,False,False,False,False,False,False,
False,False,False,False,False,False,False,False,False,False,False,
False,False,False,False,False,False,False,False,False]
for i in 0..(len(map)-1):
map[i] = bool(random(2))
return map
 
for _ in 0 ..< num_turns:
proc fixed_map(): TBoolArray =
var map2 = map
var map = [False,True,True,True,False,True,True,False,True,False,True,
False,True,False,True,False,False,True,False,False,False,False,
False,False,False,False,False,False,False,False,False]
return map
 
for i, v in pairs(map):
#make the map
map2[i] =
var map:TBoolArray
if v: neighbours(map, i) == 1
#map = random_map() # uncomment for random start
else: neighbours(map, i) == 2
map = fixed_map()
 
print_map(map,symbols)
print(map2, symbols)
for i in 0..num_turns:
 
var new_map = map
if map2 for== j in 0..(len(map)-1): break
map = map2</syntaxhighlight>
if map[j]:
{{out}}
if count_neighbours(map, j) == 2 or
<pre>_###_##_#_#_#_#__#____________
count_neighbours(map, j) == 0:
_#_#####_#_#_#________________
new_map[j] = False
__##___##_#_#_________________
else:
__##___###_#__________________
if count_neighbours(map, j) == 2:
__##___#_##___________________
new_map[j] = True
__##____###___________________
if new_map == map:
__##____#_#___________________
print_map(map,symbols)
__##_____#____________________
break
__##__________________________
map = new_map
__##__________________________</pre>
print_map(map,symbols)
</lang>
Example output:
<pre>_###_##_#_#_#_#__#_____________
_#_#####_#_#_#_________________
__##___##_#_#__________________
__##___###_#___________________
__##___#_##____________________
__##____###____________________
__##____#_#____________________
__##_____#_____________________
__##___________________________
__##___________________________</pre>
 
'''Using a string character counting method''':
<syntaxhighlight lang="nim">import strutils
<lang nimrod>const
 
const
s_init: string = "_###_##_#_#_#_#__#__"
arrLen: int = 20
var q0: string = s_init & repeatCharrepeat(arrLen-20,'_',arrLen-20)
var q1: string = q0
 
Line 2,181 ⟶ 3,925:
proc evolve(q: string): string =
result = repeatCharrepeat(arrLen,'_',arrLen)
#result[0] = '_'
for i in 1 .. q.len-1:
Line 2,192 ⟶ 3,936:
q0 = q1
q1 = evolve(q0)
echo(q1)</langsyntaxhighlight>
{{out}}
Example output:
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
Line 2,204 ⟶ 3,948:
__##________________
__##________________</pre>
 
'''Using nested functions and method calling style:'''
<syntaxhighlight lang="nim">proc cellAutomata =
proc evolveInto(x, t : var string) =
for i in x.low..x.high:
let
alive = x[i] == 'o'
left = if i == x.low: false else: x[i - 1] == 'o'
right = if i == x.high: false else: x[i + 1] == 'o'
t[i] =
if alive: (if left xor right: 'o' else: '.')
else: (if left and right: 'o' else: '.')
 
var
x = ".ooo.oo.o.o.o.o..o.."
t = x
 
for i in 1..10:
x.echo
x.evolveInto t
swap t, x
 
cellAutomata()</syntaxhighlight>
 
{{out}}
<pre>.ooo.oo.o.o.o.o..o..
.o.ooooo.o.o.o......
..oo...oo.o.o.......
..oo...ooo.o........
..oo...o.oo.........
..oo....ooo.........
..oo....o.o.........
..oo.....o..........
..oo................
..oo................</pre>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">let get g i =
try g.(i)
with _ -> 0
Line 2,235 ⟶ 4,014:
else print_char '#'
done;
print_newline()</langsyntaxhighlight>
 
put the code above in a file named "life.ml", and then use it in the ocaml toplevel like this:
and then use it in the ocaml toplevel like this:
 
<pre style="height:48ex;overflow:scroll">
Line 2,266 ⟶ 4,046:
Generation 9: __##________________
- : unit = ()
</pre>
 
=={{header|Oforth}}==
 
<syntaxhighlight lang="oforth">: nextGen( l )
| i s |
l byteSize dup ->s String newSize
s loop: i [
i 1 if=: [ 0 ] else: [ i 1- l byteAt '#' = ]
i l byteAt '#' = +
i s if=: [ 0 ] else: [ i 1+ l byteAt '#' = ] +
2 if=: [ '#' ] else: [ '_' ] over add
]
;
: gen( l n -- )
l dup .cr #[ nextGen dup .cr ] times( n ) drop ;</syntaxhighlight>
 
{{out}}
<pre>
"_###_##_#_#_#_#__#__" 10 gen
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________
__##________________
ok
</pre>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
A0 = {List.toTuple unit "_###_##_#_#_#_#__#__"}
 
Line 2,304 ⟶ 4,117:
do
{System.showInfo "Gen. "#I#": "#{Record.toList A}}
end</langsyntaxhighlight>
 
{{out}}
Output:
<pre>Gen. 0: _###_##_#_#_#_#__#__
Gen. 1: _#_#####_#_#_#______
Line 2,318 ⟶ 4,131:
Gen. 9: __##________________
</pre>
 
=={{header|PARI/GP}}==
This version defines the fixed cells to the left and right as dead; of course other versions are possible. This function generates one generation from a previous one, passed as a 0-1 vector.
of course other versions are possible.
<lang parigp>step(v)=my(u=vector(#v),k);u[1]=v[1]&v[2];u[#u]=v[#v]&v[#v-1];for(i=2,#v-1,k=v[i-1]+v[i+1];u[i]=if(v[i],k==1,k==2));u;</lang>
This function generates one generation from a previous one,
passed as a 0-1 vector.
<syntaxhighlight lang="parigp">step(v)=my(u=vector(#v),k);u[1]=v[1]&v[2];u[#u]=v[#v]&v[#v-1];for(i=2,#v-1,k=v[i-1]+v[i+1];u[i]=if(v[i],k==1,k==2));u;</syntaxhighlight>
 
To simulate a run of 10 generations of the automaton, the function above can be put in a loop that spawns a new generation as a function of nth generations passed (n=0 is the initial state):
 
<syntaxhighlight lang="parigp">cur = [0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0]; for(n=0, 9, print(cur); cur = step(cur));</syntaxhighlight>
 
=== Output ===
<syntaxhighlight lang="text">
[0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0]
[0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
</syntaxhighlight>
 
=={{header|Pascal}}==
<syntaxhighlight lang="pascal">program Test;
{$IFDEF FPC}{$MODE DELPHI}{$ELSE}{$APPTYPE}{$ENDIF}
uses
sysutils;
const
cCHAR: array[0..1] of char = ('_','#');
type
TRow = array of byte;
 
function ConvertToRow(const s:string):tRow;
var
i : NativeInt;
Begin
i := length(s);
setlength(Result,length(s));
For i := i downto 0 do
result[i-1]:= ORD(s[i]=cChar[1]);
end;
 
function OutRow(const row:tRow):string;
//create output string
var
i: NativeInt;
Begin
i := length(row);
setlength(result,i);
For i := i downto 1 do
result[i]:= cChar[row[i-1]];
end;
 
procedure NextRow(row:pByteArray;MaxIdx:NativeInt);
//compute next row in place by the using a small storage for the
//2 values, that would otherwise be overridden
var
leftValue,Value: NativeInt;
i,trpCnt: NativeInt;
Begin
leftValue := 0;
trpCnt := row[0]+row[1];
 
i := 0;
while i < MaxIdx do
Begin
Value := row[i];
//the rule for survive : PopCnt == 2
row[i] := ORD(trpCnt= 2);
//reduce popcnt of element before
dec(trpCnt,leftValue);
//goto next element
inc(i);
leftValue := Value;
//increment popcnt by right element
inc(trpCnt,row[i+1]);
//move to next position in ring buffer
end;
row[MaxIdx] := ORD(trpCnt= 2);
end;
 
const
TestString: string=' ### ## # # # # # ';
var
s: string;
row:tRow;
i: NativeInt;
begin
s := Teststring;
row:= ConvertToRow(s);
For i := 0 to 9 do
Begin
writeln(OutRow(row));
NextRow(@row[0],High(row));
end;
end.</syntaxhighlight>
{{Out}}<pre>
__###_##_#_#_#_#__#__
__#_#####_#_#_#______
___##___##_#_#_______
___##___###_#________
___##___#_##_________
___##____###_________
___##____#_#_________
___##_____#__________
___##________________
___##________________</pre>
 
=={{header|Perl}}==
Line 2,327 ⟶ 4,248:
 
Convert cells to zeros and ones to set complement state
<langsyntaxhighlight lang="perl">
$_="_###_##_#_#_#_#__#__\n";
do {
Line 2,335 ⟶ 4,256:
s/(?<=(.))(.)(?=(.))/$1 == $3 ? $1 ? 1-$2 : 0 : $2/eg;
} while ($x ne $_ and $x=$_);
</syntaxhighlight>
</lang>
 
Use hash for complement state
<langsyntaxhighlight lang="perl">
$_="_###_##_#_#_#_#__#__\n";
%h=qw(# _ _ #);
Line 2,345 ⟶ 4,266:
s/(?<=(.))(.)(?=(.))/$1 eq $3 ? $1 eq "_" ? "_" : $h{$2} : $2/eg;
} while ($x ne $_ and $x=$_);
</syntaxhighlight>
</lang>
 
{{out}} for both versions:
Both versions output:
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
Line 2,358 ⟶ 4,279:
__##________________</pre>
 
=={{header|Perl 6Phix}}==
Ludicrously optimised:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"_###_##_#_#_#_#__#__"</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">prev</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'_'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">curr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">toggled</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">prev</span><span style="color: #0000FF;">=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'#'</span> <span style="color: #008080;">or</span> <span style="color: #000000;">prev</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">130</span><span style="color: #0000FF;">-</span><span style="color: #000000;">curr</span>
<span style="color: #000000;">toggled</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">prev</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">curr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">toggled</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">s</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">toggled</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<!--</syntaxhighlight>-->
{{out}}
<pre style="font-size: 8px">
"_###_##_#_#_#_#__#__"
"_#_#####_#_#_#______"
"__##___##_#_#_______"
"__##___###_#________"
"__##___#_##_________"
"__##____###_________"
"__##____#_#_________"
"__##_____#__________"
"__##________________"
"__##________________"
</pre>
And of course I had to have a crack at that Sierpinski_Triangle:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #004080;">string</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"________________________#________________________"</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">prev</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'_'</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">curr</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">toggled</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">limit</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">24</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">prev</span><span style="color: #0000FF;">=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">130</span><span style="color: #0000FF;">-</span><span style="color: #000000;">curr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">prev</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">curr</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre style="font-size: 6px">
"________________________#________________________"
"_______________________#_#_______________________"
"______________________#___#______________________"
"_____________________#_#_#_#_____________________"
"____________________#_______#____________________"
"___________________#_#_____#_#___________________"
"__________________#___#___#___#__________________"
"_________________#_#_#_#_#_#_#_#_________________"
"________________#_______________#________________"
"_______________#_#_____________#_#_______________"
"______________#___#___________#___#______________"
"_____________#_#_#_#_________#_#_#_#_____________"
"____________#_______#_______#_______#____________"
"___________#_#_____#_#_____#_#_____#_#___________"
"__________#___#___#___#___#___#___#___#__________"
"_________#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_#_________"
"________#_______________________________#________"
"_______#_#_____________________________#_#_______"
"______#___#___________________________#___#______"
"_____#_#_#_#_________________________#_#_#_#_____"
"____#_______#_______________________#_______#____"
"___#_#_____#_#_____________________#_#_____#_#___"
"__#___#___#___#___________________#___#___#___#__"
"_#_#_#_#_#_#_#_#_________________#_#_#_#_#_#_#_#_"
</pre>
 
=={{header|Phixmonti}}==
We'll make a general algorithm capable of computing any cellular automata as defined by [[wp:Stephen Wolfram|Stephen Wolfram]]'s famous book ''[[wp:A new kind of Science|A new kind of Science]]''. We will take the liberty of wrapping the array of cells as it does not affect the result much and it makes the implementation a lot easier.
<syntaxhighlight lang="phixmonti">0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0 stklen var w
w tolist 0 0 put
0 w 1 + repeat var x2
 
10 for
<lang perl6>class Automata {
drop
has ($.rule, @.cells);
w for
method gist { <| |>.join: @!cells.map({$_ ?? '#' !! ' '}).join }
var j
method code { $.rule.fmt("%08b").comb }
j get 1 == if "#" else "_" endif print
method succ {
j 1 - get var p1 j get swap j 1 + get rot p1 + + 2 ==
self.new: :$.rule, :cells(
x2 swap j set var x2
self.code[
endfor
4 «*« @.cells.rotate(1)
nl
Z+ 2 «*« @.cells
drop x2
Z+ @.cells.rotate(-1)
endfor</syntaxhighlight>
]
)
}
}</lang>
 
=={{header|Picat}}==
The rule proposed for this task is rule 0b01101000 = 104
<syntaxhighlight lang="picat">go =>
% _ # # # _ # # _ # _ # _ # _ # _ _ # _ _
S = [0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0],
println(init=S),
run_ca(S),
nl,
 
println("Some random inits:"),
<lang perl6>my $size = 10;
_ = random2(),
my Automata $a .= new:
foreach(N in [5,10,20,50])
:rule(104),
S2 = [random() mod 2 : _I in 1..N],
:cells( 0 xx $size div 2, '111011010101'.comb, 0 xx $size div 2 );
run_ca(S2),
say $a++ for ^10;</lang>
nl
{{out}}
end.
<pre>| ### ## # # # |
 
| # ##### # # |
%
| ## ## # |
% Run a CA and show the result.
| ## ### |
%
| ## # # |
| ## # |
| ## |
| ## |
| ## |
| ## |</pre>
 
% rule/1 is the default
Rule 104 is not particularly interesting so here is [[wp:Rule 90|Rule 90]], which shows a [[wp:Sierpinski Triangle|Sierpinski Triangle]].
run_ca(S) =>
run_ca(S,rule).
run_ca(S,Rules) =>
Len = S.length,
All := [S],
Seen = new_map(), % detect fixpoint and cycle
while (not Seen.has_key(S))
Seen.put(S,1),
T = [S[1]] ++ [apply(Rules, slice(S,I-1,I+1)) : I in 2..Len-1] ++ [S[Len]],
All := All ++ [T],
S := T
end,
foreach(A in All) println(A.convert()) end,
writeln(len=All.length).
 
% Convert:
<lang perl6>my $size = 50;
% 0->"_"
my Automata $a .= new: :rule(90), :cells( 0 xx $size div 2, 1, 0 xx $size div 2 );
% 1->"#"
convert(L) = Res =>
B = "_#",
Res = [B[L[I]+1] : I in 1..L.length].
 
% the rules
say $a++ for ^20;</lang>
rule([0,0,0]) = 0. %
rule([0,0,1]) = 0. %
rule([0,1,0]) = 0. % Dies without enough neighbours
rule([0,1,1]) = 1. % Needs one neighbour to survive
rule([1,0,0]) = 0. %
rule([1,0,1]) = 1. % Two neighbours giving birth
rule([1,1,0]) = 1. % Needs one neighbour to survive
rule([1,1,1]) = 0. % Starved to death.</syntaxhighlight>
 
{{out}}
<pre>init = [0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0]
<pre>| # |
_###_##_#_#_#_#__#__
| # # |
_#_#####_#_#_#______
| # # |
__##___##_#_#_______
| # # # # |
__##___###_#________
| # # |
__##___#_##_________
| # # # # |
__##____###_________
| # # # # |
__##____#_#_________
| # # # # # # # # |
__##_____#__________
| # # |
__##________________
| # # # # |
__##________________
| # # # # |
len = 10
| # # # # # # # # |
 
| # # # # |
Some random inits:
| # # # # # # # # |
_###_
| # # # # # # # # |
_#_#_
| # # # # # # # # # # # # # # # # |
__#__
| # # |
_____
| # # # # |
_____
| # # # # |
len = 5
| # # # # # # # # |</pre>
 
_#___##_#_
_____###__
_____#_#__
______#___
__________
__________
len = 6
 
###__####_#___#___##
#_#__#__##________##
##______##________##
##______##________##
len = 4
 
______###_#_#___####__#_______#__#___#_####__#_###
______#_##_#____#__#__________________##__#___##_#
_______####___________________________##______####
_______#__#___________________________##______#__#
______________________________________##_________#
______________________________________##_________#
len = 6</pre>
 
 
The program is fairly general. Here's the additional code for the rule 30 CA.
<syntaxhighlight lang="picat">go2 =>
N = 4,
Ns = [0 : _ in 1..N],
S = Ns ++ [1] ++ Ns,
run_ca(S, rule30).
 
% The rules for rule 30
rule30([0,0,0]) = 0.
rule30([0,0,1]) = 1.
rule30([0,1,0]) = 1.
rule30([0,1,1]) = 1.
rule30([1,0,0]) = 1.
rule30([1,0,1]) = 0.
rule30([1,1,0]) = 0.
rule30([1,1,1]) = 0.</syntaxhighlight>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(let Cells (chop "_###_##_#_#_#_#__#__")
(do 10
(prinl Cells)
Line 2,440 ⟶ 4,504:
(link "#") ) ) )
Cells )
(link "_") ) ) ) )</langsyntaxhighlight>
{{out}}
Output:
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
Line 2,455 ⟶ 4,519:
=={{header|Prolog}}==
Works ith SWI-Prolog.
<langsyntaxhighlight Prologlang="prolog">one_dimensional_cellular_automata(L) :-
maplist(my_write, L), nl,
length(L, N),
Line 2,490 ⟶ 4,554:
% the last four possibilies =>
% we consider that there is à 0 after the end
complang jq># The 1-d cellular automaton:
compute_next([0, 0], [0]).
def next:
# Conveniently, jq treats null as 0 when it comes to addition
# so there is no need to fiddle with the boundaries
. as $old
| reduce range(0; length) as $i
([];
($old[$i-1] + $old[$i+1]) as $s
| if $s == 0 then .[$i] = 0
elif $s == 1 then .[$i] = (if $old[$i] == 1 then 1 else 0 end)
else .[$i] = (if $old[$i] == 1 then 0 else 1 end)
end);
 
 
# pretty-print an array:
def pp: reduce .[] as $i (""; . + (if $i == 0 then " " else "*" end));
 
# continue until quiescence:
def go: recurse(. as $prev | next | if . == $prev then empty else . end) | pp;
 
# Example:
[0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0] | goute_next([0, 0], [0]).
 
compute_next([1, 0], [0]).
Line 2,507 ⟶ 4,592:
L = [0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0],
one_dimensional_cellular_automata(L).
</syntaxhighlight>
</lang>
{{out}}
Output :
<pre> ?- one_dimensional_cellular_automata.
.###.##.#.#.#.#..#..
Line 2,521 ⟶ 4,606:
true .
</pre>
 
=={{header|PureBasic}}==
<lang PureBasic>EnableExplicit
Dim cG.i(21)
Dim nG.i(21)
Define.i n, Gen
 
DataSection
Data.i 0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0
EndDataSection
For n=1 To 20
Read.i cG(n)
Next
 
OpenConsole()
Repeat
Print("Generation "+Str(Gen)+": ")
For n=1 To 20
Print(Chr(95-cG(n)*60))
Next
Gen +1
PrintN("")
For n=1 To 20
If (cG(n) And (cG(n-1) XOr cg(n+1))) Or (Not cG(n) And (cG(n-1) And cg(n+1)))
nG(n)=1
Else
nG(n)=0
EndIf
Next
Swap cG() , nG()
Until Gen > 9
 
PrintN("Press any key to exit"): Repeat: Until Inkey() <> ""</lang>Output:
<pre>Generation 0: _###_##_#_#_#_#__#__
Generation 1: _#_#####_#_#_#______
Generation 2: __##___##_#_#_______
Generation 3: __##___###_#________
Generation 4: __##___#_##_________
Generation 5: __##____###_________
Generation 6: __##____#_#_________
Generation 7: __##_____#__________
Generation 8: __##________________
Generation 9: __##________________</pre>
 
=={{header|Python}}==
===Procedural===
===Python: Straightforward interpretation of spec===
====Python: Straightforward interpretation of spec====
<lang python>import random
<syntaxhighlight lang="python">import random
 
printdead, printlive = '_#'
Line 2,591 ⟶ 4,634:
universe.replace('0', printdead).replace('1', printlive) )
universe = offendvalue + universe + offendvalue
universe = ''.join(neighbours2newstate[universe[i:i+3]] for i in range(cellcount))</langsyntaxhighlight>
{{out}}
Sample output:
<pre>Generation 0: _###_##_#_#_#_#__#__
Generation 1: _#_#####_#_#_#______
Line 2,604 ⟶ 4,647:
Generation 9: __##________________</pre>
 
====Python: Using boolean operators on bits====
The following implementation uses boolean operations to realize the function.
<langsyntaxhighlight lang="python">import random
 
nquads = 5
Line 2,621 ⟶ 4,664:
print "Generation %3i: %s" % (i,(''.join(tr[int(t,16)] for t in (fmt%(a>>1)))))
a |= endvals
a = ((a&((a<<1) | (a>>1))) ^ ((a<<1)&(a>>1))) & endmask</langsyntaxhighlight>
 
====Python: Sum neighbours == 2====
This example makes use of the observation that a cell is alive in the next generation if the sum with its current neighbours of alive cells is two.
<langsyntaxhighlight lang="python">>>> gen = [ch == '#' for ch in '_###_##_#_#_#_#__#__']
>>> for n in range(10):
print(''.join('#' if cell else '_' for cell in gen))
Line 2,642 ⟶ 4,685:
__##________________
__##________________
>>> </langsyntaxhighlight>
 
===Composition of pure functions===
 
Interpreting the rule shown in the task description as Wolfram rule 104, and generalising enough to allow for other rules of this kind:
<syntaxhighlight lang="python">'''Cellular Automata'''
 
from itertools import islice, repeat
from functools import reduce
from random import randint
 
 
# nextRowByRule :: Int -> [Bool] -> [Bool]
def nextRowByRule(intRule):
'''A row of booleans derived by Wolfram rule n
from another boolean row of the same length.
'''
# step :: (Bool, Bool, Bool) -> Bool
def step(l, x, r):
return bool(intRule & 2**intFromBools([l, x, r]))
 
# go :: [Bool] -> [Bool]
def go(xs):
return [False] + list(map(
step,
xs, xs[1:], xs[2:]
)) + [False]
return go
 
 
# intFromBools :: [Bool] -> Int
def intFromBools(xs):
'''Integer derived by binary interpretation
of a list of booleans.
'''
def go(b, pn):
power, n = pn
return (2 * power, n + power if b else n)
return foldr(go)([1, 0])(xs)[1]
 
 
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Samples of Wolfram rule evolutions.
'''
print(
unlines(map(showRuleSample, [104, 30, 110]))
)
 
 
# ----------------------- DISPLAY ------------------------
 
# showRuleSample :: Int -> String
def showRuleSample(intRule):
'''16 steps in the evolution
of a given Wolfram rule.
'''
return 'Rule ' + str(intRule) + ':\n' + (
unlines(map(
showCells,
take(16)(
iterate(nextRowByRule(intRule))(
onePixelInLineOf(64) if (
bool(randint(0, 1))
) else randomPixelsInLineOf(64)
)
)
))
)
 
 
# boolsFromInt :: Int -> [Bool]
def boolsFromInt(n):
'''List of booleans derived by binary
decomposition of an integer.
'''
def go(x):
return Just((x // 2, bool(x % 2))) if x else Nothing()
return unfoldl(go)(n)
 
 
# nBoolsFromInt :: Int -> Int -> [Bool]
def nBoolsFromInt(n):
'''List of bools, left-padded to given length n,
derived by binary decomposition of an integer x.
'''
def go(n, x):
bs = boolsFromInt(x)
return list(repeat(False, n - len(bs))) + bs
return lambda x: go(n, x)
 
 
# onePixelInLineOf :: Int -> [Bool]
def onePixelInLineOf(n):
'''A row of n (mainly False) booleans,
with a single True value in the middle.
'''
return nBoolsFromInt(n)(
2**(n // 2)
)
 
 
# randomPixelsInLineOf :: Int -> [Bool]
def randomPixelsInLineOf(n):
'''A row of n booleans with pseudorandom values.
'''
return [bool(randint(0, 1)) for _ in range(1, 1 + n)]
 
 
# showCells :: [Bool] -> String
def showCells(xs):
'''A block string representation of a list of booleans.
'''
return ''.join([chr(9608) if x else ' ' for x in xs])
 
 
# ----------------------- GENERIC ------------------------
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.
Wrapper containing the result of a computation.
'''
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
 
# Nothing :: () -> Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.
Empty wrapper returned where a computation is not possible.
'''
return {'type': 'Maybe', 'Nothing': True}
 
 
# foldr :: (a -> b -> b) -> b -> [a] -> b
def foldr(f):
'''Right to left reduction of a list,
using the binary operator f, and
starting with an initial accumulator value.
'''
def g(a, x):
return f(x, a)
return lambda acc: lambda xs: reduce(
g, xs[::-1], acc
)
 
 
# iterate :: (a -> a) -> a -> Gen [a]
def iterate(f):
'''An infinite list of repeated
applications of f to x.
'''
def go(x):
v = x
while True:
yield v
v = f(v)
return go
 
 
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.
'''
def go(xs):
return (
xs[0:n]
if isinstance(xs, (list, tuple))
else list(islice(xs, n))
)
return go
 
 
# unfoldl :: (b -> Maybe (b, a)) -> b -> [a]
def unfoldl(f):
'''Dual to reduce or foldl.
Where these reduce a list to a summary value, unfoldl
builds a list from a seed value.
Where f returns Just(a, b), a is appended to the list,
and the residual b is used as the argument for the next
application of f.
When f returns Nothing, the completed list is returned.
'''
def go(v):
x, r = v, v
xs = []
while True:
mb = f(x)
if mb.get('Nothing'):
return xs
else:
x, r = mb.get('Just')
xs.insert(0, r)
return xs
return go
 
 
# unlines :: [String] -> String
def unlines(xs):
'''A single string formed by the intercalation
of a list of strings with the newline character.
'''
return '\n'.join(xs)
 
 
# MAIN -------------------------------------------------
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>Rule 104:
█ █ ████ ██ █ █ █ █ █ ██ █████ ██ ██ █ ██
█ █ ██ █ █ ███ █ ████ ██ ███
██ █ ██ █ █ █ ██ █ █
██ ████ ██ █
██ █ █ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
██ ██
Rule 30:
███
██ █
██ ████
██ █ █
██ ████ ███
██ █ █ █
██ ████ ██████
██ █ ███ █
██ ████ ██ █ ███
██ █ █ ████ ██ █
██ ████ ██ █ █ ████
██ █ ███ ██ ██ █ █
██ ████ ██ ███ ███ ██ ███
██ █ █ ███ █ ███ █ █
██ ████ ██ █ █ █████ ███████
Rule 110:
█ █ ██ ██ ██ █ █ ██ ███ █ █ ███ ██ ██ █ █ █
██ ██████ ███ ████ ███ ██ ███████ █ ██████ ██ ██ ██
█████ ███ ███ ███ ██████ ███ ██ █ ███ ███ ███
█ █ ██ ███ █ ██ ███ █ ██ █ ███ ██ ██ █ ██ ███ █
█ ██ █████ ████████ █ ██ █████ ██ █ █████████████ ███
█ ███ ██ ███ ███ ███ ██ ██████ ██ ███ █
███ ████ ██ █ ██ █ ██ █ ███ ██ ████ ██ ███
█ ███ █ █████ ████████████ █ ███ ██ █ █████ █
███ █ ████ █ ██ █████ █ ███ ██ ██ ███
█ █████ █ ██ ███ ██ ███ ██ ████ ███ ██ █
███ █ ██ ███ ██ █ ███ ██ ██████ █ ██ █ █████
█ █ ███████ ██████ ██ █ █████ █ ██ ███████ █
███ ██ ███ █ ███████ █ █████ ██ █ ██
█ ████ ██ █ ██ ██ █ ██ ██ █ ███ ██ ███
███ █ █████ ███ ███ ██ ███ ███ ██ ██ █ █████ █
█ █ ██ ██ █ ██ █ ██ █ █████ ███ █ ███ █████ ██ ███ </pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ stack 0 ] is cells ( --> s )
 
[ dup size cells replace
0 swap witheach
[ char # =
| 1 << ] ] is setup ( $ --> n )
 
[ 0 swap
cells share times
[ dup i >> 7 &
[ table 0 0 0 1 0 1 1 0 ]
rot 1 << | swap ]
drop 1 << ] is nextline ( n --> n )
 
[ cells share times
[ dup i 1+ bit &
iff [ char # ]
else [ char _ ]
emit ]
cr drop ] is echoline ( n --> )
 
[ setup
[ dup echoline
dup nextline
tuck = until ]
echoline ] is automate ( $ --> )
 
$ "_###_##_#_#_#_#__#__" automate</syntaxhighlight>
 
{{out}}
 
<pre>_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________
</pre>
 
 
=={{header|R}}==
 
<langsyntaxhighlight Rlang="r">set.seed(15797, kind="Mersenne-Twister")
 
maxgenerations = 10
Line 2,678 ⟶ 5,029:
universe <- cellularAutomata(universe, stayingAlive)
cat(format(i, width=3), deadOrAlive2string(universe), "\n")
}</langsyntaxhighlight>
 
{{out}}
Sample output,
<pre>
1 _##_____####_#___#_#__
Line 2,695 ⟶ 5,046:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket
 
(define (update cells)
Line 2,721 ⟶ 5,072:
(0 0 1 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0)
(0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
(0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0) |#</langsyntaxhighlight>
 
Below is an alternative implementation using graphical output in the Racket REPL.
It works with DrRacket and Emacs + Geiser.
<syntaxhighlight lang="racket">#lang slideshow
 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Simulation of cellular automata, as described by Stephen Wolfram in his 1983 paper.
;; Uses Racket's inline image display capability for visual presentation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
(require racket/draw)
(require slideshow)
 
(define *rules* '((1 1 1) (1 1 0) (1 0 1) (1 0 0)
(0 1 1) (0 1 0) (0 0 1) (0 0 0)))
 
(define (bordered-square n)
(filled-rectangle n n #:draw-border? #t))
 
(define (draw-row lst)
(apply hc-append 2 (map (λ (x) (colorize (bordered-square 10) (cond ((= x 0) "gray")
((= x 1) "red")
(else "gray"))))
lst)))
 
(define (extract-neighborhood nth prev-row)
(take (drop (append '(0) prev-row '(0)) nth) 3))
 
(define (automaton-to-bits n)
(reverse (map (λ (y) (if (zero? (bitwise-and y n)) 0 1))
(map (λ (x) (expt 2 x)) (range 0 8)))))
 
(define (get-rules bits)
(map cdr (filter (λ (x) (= (car x) 1)) (map cons bits *rules*))))
 
(define (advance-row old-row rules)
(let ([new '()])
(for ([i (in-range 0 (length old-row))])
(set! new (cons (if (member (extract-neighborhood i old-row)
rules) 1 0) new)))
(reverse new)))
 
(define (draw-automaton automaton init-row row-number)
(let* ([bit-representation (automaton-to-bits automaton)]
[rules (get-rules bit-representation)]
[rows (list init-row)])
(for ([i (in-range 1 row-number)])
(set! rows (cons (advance-row (car rows) rules)
rows)))
(apply vc-append 2 (map draw-row (reverse rows)))))
 
(draw-automaton 104 '(0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0) 10)</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|rakudo|2014-02-27}}
We'll make a general algorithm capable of computing any cellular automata
as defined by [[wp:Stephen Wolfram|Stephen Wolfram]]'s
famous book ''[[wp:A new kind of Science|A new kind of Science]]''.
We will take the liberty of wrapping the array of cells
as it does not affect the result much
and it makes the implementation a lot easier.
 
<syntaxhighlight lang="raku" line>class Automaton {
has $.rule;
has @.cells;
has @.code = $!rule.fmt('%08b').flip.comb».Int;
method gist { "|{ @!cells.map({+$_ ?? '#' !! ' '}).join }|" }
method succ {
self.new: :$!rule, :@!code, :cells(
@!code[
4 «*« @!cells.rotate(-1)
»+« 2 «*« @!cells
»+« @!cells.rotate(1)
]
)
}
}
 
# The rule proposed for this task is rule 0b01101000 = 104
 
my @padding = 0 xx 5;
my Automaton $a .= new:
rule => 104,
cells => flat @padding, '111011010101'.comb, @padding
;
say $a++ for ^10;
 
 
# Rule 104 is not particularly interesting so here is [[wp:Rule 90|Rule 90]],
# which shows a [[wp:Sierpinski Triangle|Sierpinski Triangle]].
 
say '';
@padding = 0 xx 25;
$a = Automaton.new: :rule(90), :cells(flat @padding, 1, @padding);
say $a++ for ^20;</syntaxhighlight>
 
{{out}}
<pre>
| ### ## # # # |
| # ##### # # |
| ## ## # |
| ## ### |
| ## # # |
| ## # |
| ## |
| ## |
| ## |
| ## |
 
| # |
| # # |
| # # |
| # # # # |
| # # |
| # # # # |
| # # # # |
| # # # # # # # # |
| # # |
| # # # # |
| # # # # |
| # # # # # # # # |
| # # # # |
| # # # # # # # # |
| # # # # # # # # |
| # # # # # # # # # # # # # # # # |
| # # |
| # # # # |
| # # # # |
| # # # # # # # # |
</pre>
 
=={{header|Red}}==
<syntaxhighlight lang="rebol">Red [
Purpose: "One-dimensional cellular automata"
Author: "Joe Smith"
]
 
vals: [0 1 0]
kill: [[0 0] [#[none] 0] [0 #[none]]]
evo: function [petri] [
new-petri: copy petri
while [petri/1] [
if all [petri/-1 = 1 petri/2 = 1] [new-petri/1: select vals petri/1]
if find/only kill reduce [petri/-1 petri/2] [new-petri/1: 0]
petri: next petri new-petri: next new-petri
]
petri: head petri new-petri: head new-petri
clear insert petri new-petri
]
 
display: function [petri] [
print replace/all (replace/all to-string petri "0" "_") "1" "#"
petri
]
 
loop 10 [
evo display [1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0]
]
</syntaxhighlight>
 
{{out}}
<pre>
###_##_#_#_#_#__#_
#_#####_#_#_#_____
_##___##_#_#______
_##___###_#_______
_##___#_##________
_##____###________
_##____#_#________
_##_____#_________
_##_______________
_##_______________
</pre>
 
=={{header|Retro}}==
<syntaxhighlight lang="retro"># 1D Cellular Automota
 
Assume an array of cells with an initial distribution of live and
dead cells, and imaginary cells off the end of the array having
fixed values.
 
Cells in the next generation of the array are calculated based on
the value of the cell and its left and right nearest neighbors in
the current generation.
 
If, in the following table, a live cell is represented by 1 and a
dead cell by 0 then to generate the value of the cell at a particular
index in the array of cellular values you use the following table:
 
000 -> 0 #
001 -> 0 #
010 -> 0 # Dies without enough neighbours
011 -> 1 # Needs one neighbour to survive
100 -> 0 #
101 -> 1 # Two neighbours giving birth
110 -> 1 # Needs one neighbour to survive
111 -> 0 # Starved to death.
 
I had originally written an implementation of this in RETRO 11.
For RETRO 12 I took advantage of new language features and some
further considerations into the rules for this task.
 
The first word, `string,` inlines a string to `here`. I'll use
this to setup the initial input.
 
~~~
:string, (s-) [ , ] s:for-each #0 , ;
~~~
 
The next two lines setup an initial generation and a buffer for
the evolved generation. In this case, `This` is the current
generation and `Next` reflects the next step in the evolution.
 
~~~
'This d:create
'.###.##.#.#.#.#..#.. string,
'Next d:create
'.................... string,
~~~
 
I use `display` to show the current generation.
 
~~~
:display (-)
&This s:put nl ;
~~~
 
As might be expected, `update` copies the `Next` generation to
the `This` generation, setting things up for the next cycle.
 
~~~
:update (-)
&Next &This dup s:length copy ;
~~~
 
The word `group` extracts a group of three cells. This data will
be passed to `evolve` for processing.
 
~~~
:group (a-nnn)
[ fetch ]
[ n:inc fetch ]
[ n:inc n:inc fetch ] tri ;
~~~
 
I use `evolve` to decide how a cell should change, based on its
initial state with relation to its neighbors.
 
In the prior implementation this part was much more complex as I
tallied things up and had separate conditions for each combination.
This time I take advantage of the fact that only cells with two
neighbors will be alive in the next generation. So the process is:
 
- take the data from `group`
- compare to `$#` (for living cells)
- add the flags
- if the result is `#-2`, the cell should live
- otherwise it'll be dead
 
~~~
:evolve (nnn-c)
[ $# eq? ] tri@ + +
#-2 eq? [ $# ] [ $. ] choose ;
~~~
 
For readability I separated out the next few things. `at` takes an
index and returns the address in `This` starting with the index.
 
~~~
:at (n-na)
&This over + ;
~~~
 
The `record` word adds the evolved value to a buffer. In this case
my `generation` code will set the buffer to `Next`.
 
~~~
:record (c-)
buffer:add n:inc ;
~~~
 
And now to tie it all together. Meet `generation`, the longest bit
of code in this sample. It has several bits:
 
- setup a new buffer pointing to `Next`
 
- this also preserves the old buffer
 
- setup a loop for each cell in `This`
 
- initial loop index at -1, to ensure proper dummy state for first cell
- get length of `This` generation
 
- perform a loop for each item in the generation, updating `Next` as it goes
 
- copy `Next` to `This` using `update`.
 
~~~
:generation (-)
[ &Next buffer:set
#-1 &This s:length
[ at group evolve record ] times drop
update
] buffer:preserve ;
~~~
 
The last bit is a helper. It takes a number of generations and displays
the state, then runs a `generation`.
 
~~~
:generations (n-)
[ display generation ] times ;
~~~
 
And a text. The output should be:
 
.###.##.#.#.#.#..#..
.#.#####.#.#.#......
..##...##.#.#.......
..##...###.#........
..##...#.##.........
..##....###.........
..##....#.#.........
..##.....#..........
..##................
..##................
 
~~~
#10 generations
~~~</syntaxhighlight>
 
=={{header|REXX}}==
This REXX version will show (as a default) &nbsp; 40 &nbsp; generations, &nbsp; or less if the generations of cellular automata repeat.
<langsyntaxhighlight lang="rexx">/*REXX pgmprogram generates & displays N generations of one-dimensional one─dimensional cellular automata. */
parse arg $ limitgens .; if $=='' | $==',' then $=001110110101010 /*defaultobtain optional arguments from the CL*/
if if limit$=='' | $=="," then limit$=40001110110101010 /*Not specified? Then use the /*default.*/
if gens=='' | gens=="," then gens=40 /* " " " " " " */
 
do #=0 for gens /* process the one-dimensional cells.*/
do gen=0 to limit
say ' " generation'" right(gen#,length(limitgens)) ' ' translate($,' "'", 10)
@='·'0 /*next gener[↓] generation.*/
do j=2 tofor length($) - 1; x=substr($, j-1, 3) /*getobtain athe cell.*/
if x==011 | x==101 | x==110 then @=overlay(1, @, j) /*the cell lives. */
else @=overlay(0, @, j) /*cell " " dies. */
end /*j*/
 
if $==@ then do; say right('repeats',40); leave; end /*it repeats?*/
if $==@ then do; say right('repeats', 40); leave; end /*now use the next gendoes ofit cells.repeat? */
$=@ /*now use the next generation of cells.*/
end /*gen*/
end /*#*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
'''output''' when using the default input:
<pre>
<pre style="overflow:scroll">
generation 0 ··###·##·#·#·#·
generation 1 ··#·#####·#·#··
Line 2,751 ⟶ 5,439:
</pre>
 
=={{header|RetroRing}}==
<syntaxhighlight lang="ring">
<lang Retro>{{
# Project : One-dimensional cellular automata
: $, ( $- ) withLength [ @+ , ] times @ , ;
create this ".###.##.#.#.#.#..#.." $,
create next this getLength allot
create group "..." $,
variable neighbours
 
rule = ["0", "0", "0", "1", "0", "1", "1", "0"]
: reset 0 !neighbours ;
now = "01110110101010100100"
: hasNeighbour? @ '# = [ neighbours ++ ] ifTrue ;
: countNeighboursOnEdge '# = [ 1 ] [ 0 ] if !neighbours ;
for generation = 0 to 9
: flip dup this + @ '# = [ '. ] [ '# ] if ;
see "generation " + generation + ": " + now + nl
: extract dup this + 1- group 3 copy ;
nxt = ""
for cell = 1 to len(now)
str = "bintodec(" + '"' +substr("0"+now+"0", cell, 3) + '"' + ")"
eval("p=" + str)
nxt = nxt + rule[p+1]
next
temp = nxt
nxt = now
now = temp
next
 
func bintodec(bin)
: count
binsum = 0
( left ) [ 0 = ] [ @this countNeighboursOnEdge ] when
for n=1 to len(bin)
( right ) [ 19 = ] [ this 19 + @ countNeighboursOnEdge ] when
binsum = binsum + number(bin[n]) *pow(2, len(bin)-n)
( middle ) reset extract group dup 2 + 2hasNeighbour? ;
next
return binsum
</syntaxhighlight>
Output:
<pre>
generation 0: 01110110101010100100
generation 1: 01011111010101000000
generation 2: 00110001101010000000
generation 3: 00110001110100000000
generation 4: 00110001011000000000
generation 5: 00110000111000000000
generation 6: 00110000101000000000
generation 7: 00110000010000000000
generation 8: 00110000000000000000
generation 9: 00110000000000000000
</pre>
 
=={{header|RPL}}==
: process
Rather than assuming fixed values for cells beyond borders, it has been decided to make the board 'circular', as it is the case in many 2D versions. A new generation is directly derived from the output string of the previous generation.
reset count @neighbours
{{works with|Halcyon Calc|4.2.7}}
[ 0 = ] [ drop dup next + '. swap ! ] when
≪ 1 10 START
[ 1 = ] [ drop dup this + @ over next + ! ] when
DUP DUP 1 1 SUB
[ 2 = ] [ drop flip over next + ! ] when
OVER DUP SIZE DUP SUB ROT + SWAP +
drop ;
{ "_##" "#_#" "##_" }
→ gen lives
≪ "" 2 gen SIZE 1 - FOR j
lives gen j 1 - DUP 2 + SUB POS "#" "_" IFTE +
NEXT
NEXT
'CELLS' STO
 
"_###_##_#_#_#_#__#__" CELLS
: generation
{{out}}
0 this getLength
<pre>
[ process 1+ ] times drop
10: _###_##_#_#_#_#__#__
next this withLength copy ;
9: _#_#####_#_#_#______
---reveal---
8: __##___##_#_#_______
: generations
7: __##___###_#________
cr 0 swap [ [ this swap "%d %s\n" puts ] sip generation 1+ ] times drop ;
6: __##___#_##_________
}}</lang>
5: __##____###_________
 
4: __##____#_#_________
Sample Output:
3: __##_____#__________
 
2: __##________________
<pre>10 generations
1: __##________________
0 .###.##.#.#.#.#..#..
</pre>
1 .#.#####.#.#.#......
2 ..##...##.#.#.......
3 ..##...###.#........
4 ..##...#.##.........
5 ..##....###.........
6 ..##....#.#.........
7 ..##.....#..........
8 ..##................
9 ..##................</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">def evolve(ary)
([0]+ary+[0]).each_cons(3).map{|a,b,c| a+b+c == 2 ? 1 : 0}
end
Line 2,813 ⟶ 5,524:
until ary == (new = evolve(ary))
printit ary = new
end</langsyntaxhighlight>
{{out}}
<pre>.###.##.#.#.#.#..#..
Line 2,824 ⟶ 5,535:
..##.....#..........
..##................</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn get_new_state(windowed: &[bool]) -> bool {
match windowed {
[false, true, true] | [true, true, false] => true,
_ => false
}
}
 
fn next_gen(cell: &mut [bool]) {
let mut v = Vec::with_capacity(cell.len());
v.push(cell[0]);
for i in cell.windows(3) {
v.push(get_new_state(i));
}
v.push(cell[cell.len() - 1]);
cell.copy_from_slice(&v);
}
 
fn print_cell(cell: &[bool]) {
for v in cell {
print!("{} ", if *v {'#'} else {' '});
}
println!();
}
 
fn main() {
 
const MAX_GENERATION: usize = 10;
const CELLS_LENGTH: usize = 30;
 
let mut cell: [bool; CELLS_LENGTH] = rand::random();
 
for i in 1..=MAX_GENERATION {
print!("Gen {:2}: ", i);
print_cell(&cell);
next_gen(&mut cell);
}
}
</syntaxhighlight>
 
=={{header|Scala}}==
{{works with|Scala|2.8}}
<langsyntaxhighlight lang="scala">def cellularAutomata(s: String) = {
def it = Iterator.iterate(s) ( generation =>
("_%s_" format generation).iterator
Line 2,837 ⟶ 5,588:
(it drop 1) zip it takeWhile Function.tupled(_ != _) map (_._2) foreach println
}</langsyntaxhighlight>
 
Sample:
Line 2,855 ⟶ 5,606:
=={{header|Scheme}}==
{{Works with|Scheme|R<math>^5</math>RS}}
<langsyntaxhighlight lang="scheme">(define (next-generation left petri-dish right)
(if (null? petri-dish)
(list)
Line 2,875 ⟶ 5,626:
(- generations 1)))))
 
(display-evolution (list 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0) 10)</langsyntaxhighlight>
Output:
<pre>(1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0)
Line 2,891 ⟶ 5,642:
A graphical cellular automaton can be found [http://seed7.sourceforge.net/algorith/graphic.htm#cellauto here].
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const string: start is "_###_##_#_#_#_#__#__";
Line 2,916 ⟶ 5,667:
g0 := g1;
end for;
end func;</langsyntaxhighlight>
 
Output:
Line 2,931 ⟶ 5,682:
__##________________
__##________________
</pre>
 
=={{header|SequenceL}}==
<syntaxhighlight lang="sequencel">import <Utilities/Conversion.sl>;
 
main(args(2)) :=
run(args[1], stringToInt(args[2])) when size(args) = 2
else
"Usage error: exec <initialCells> <generations>";
 
stringToCells(string(1))[i] := 0 when string[i] = '_' else 1;
cellsToString(cells(1))[i] := '#' when cells[i] = 1 else '_';
 
run(cellsString(1), generations) :=
runHelper(stringToCells(cellsString), generations, cellsString);
 
runHelper(cells(1), generations, result(1)) :=
let
nextCells := step(cells);
in
result when generations = 0
else
runHelper(nextCells, generations - 1,
result ++ "\n" ++ cellsToString(nextCells));
 
step(cells(1))[i] :=
let
left := cells[i-1] when i > 1 else 0;
right := cells[i + 1] when i < size(cells) else 0;
in
1 when (left + cells[i] + right) = 2
else
0;</syntaxhighlight>
 
{{out}}
<pre>
"_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
__##________________
__##________________"
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">var seq = "_###_##_#_#_#_#__#__";
var x = '';
 
loop {
seq.tr!('01', '_#');
say seq;
seq.tr!('_#', '01');
seq.gsub!(/(?<=(.))(.)(?=(.))/, {|s1,s2,s3| s1 == s3 ? (s1 ? 1-s2 : 0) : s2});
(x != seq) && (x = seq) || break;
}</syntaxhighlight>
 
{{out}}
<pre>
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
</pre>
 
{{trans|Raku}}
<syntaxhighlight lang="ruby">class Automaton(rule, cells) {
 
method init {
rule = sprintf("%08b", rule).chars.map{.to_i}.reverse;
}
 
method next {
var previous = cells.map{_};
var len = previous.len;
cells[] = rule[
previous.range.map { |i|
4*previous[i-1 % len] +
2*previous[i] +
previous[i+1 % len]
}...
]
}
 
method to_s {
cells.map { _ ? '#' : ' ' }.join;
}
}
 
var size = 10;
var auto = Automaton(
rule: 104,
cells: [(size/2).of(0)..., 111011010101.digits..., (size/2).of(0)...],
);
 
size.times {
say "|#{auto}|";
auto.next;
}</syntaxhighlight>
 
{{out}}
<pre>
| ### ## # # # |
| # ##### # # |
| ## ## # |
| ## ### |
| ## # # |
| ## # |
| ## |
| ## |
| ## |
| ## |
</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">proc evolve {a} {
set new [list]
for {set i 0} {$i < [llength $a]} {incr i} {
Line 2,969 ⟶ 5,842:
set array $new
print $array
}</langsyntaxhighlight>
 
=={{header|Ursala}}==
Line 2,978 ⟶ 5,851:
it according to the rule. The cells are maintained as a list of booleans
(0 and &) but are converted to characters for presentation in the example code.
<langsyntaxhighlight Ursalalang="ursala">#import std
#import nat
 
Line 2,989 ⟶ 5,862:
#show+
 
example = ~&?(`#!,`.!)** evolve10 <0,&,&,&,0,&,&,0,&,0,&,0,&,0,0,&,0,0></langsyntaxhighlight>
output:
<pre>
Line 3,003 ⟶ 5,876:
..##..............
..##..............</pre>
 
 
=={{header|Vedit macro language}}==
 
This implementation writes the calculated patterns into an edit buffer, where the results can viewed and saved into a file if required. The edit buffer also acts as storage during calculations.
<langsyntaxhighlight lang="vedit">IT("Gen 0: ..###.##.#.#.#.#..#.....") // initial pattern
#9 = Cur_Col
 
Line 3,025 ⟶ 5,897:
IT("Gen ") Num_Ins(#8, LEFT+NOCR) IT(": ")
Reg_Ins(20)
}</langsyntaxhighlight>
 
Sample output:
<langsyntaxhighlight lang="vedit">Gen 0: ..###.##.#.#.#.#..#.....
Gen 1: ..#.#####.#.#.#.........
Gen 2: ...##...##.#.#..........
Line 3,037 ⟶ 5,909:
Gen 7: ...##.....#.............
Gen 8: ...##...................
Gen 9: ...##...................</langsyntaxhighlight>
 
=={{header|Visual Basic .NET}}==
 
This implementation is run from the command line. The command is followed by a string of either 1's or #'s for an active cell, or 0's or _'s for an inactive one.
 
<lang Visual Basic .NET>Imports System.Text
 
Module CellularAutomata
 
Private Enum PetriStatus
Active
Stable
Dead
End Enum
 
Function Main(ByVal cmdArgs() As String) As Integer
If cmdArgs.Length = 0 Or cmdArgs.Length > 1 Then
Console.WriteLine("Command requires string of either 1s and 0s or #s and _s.")
Return 1
End If
 
Dim petriDish As BitArray
 
Try
petriDish = InitialisePetriDish(cmdArgs(0))
Catch ex As Exception
Console.WriteLine(ex.Message)
Return 1
End Try
 
Dim generation As Integer = 0
Dim ps As PetriStatus = PetriStatus.Active
 
Do While True
If ps = PetriStatus.Stable Then
Console.WriteLine("Sample stable after {0} generations.", generation - 1)
Exit Do
Else
Console.WriteLine("{0}: {1}", generation.ToString("D3"), BuildDishString(petriDish))
If ps = PetriStatus.Dead Then
Console.WriteLine("Sample dead after {0} generations.", generation)
Exit Do
End If
End If
 
ps = GetNextGeneration(petriDish)
generation += 1
Loop
 
Return 0
End Function
 
Private Function InitialisePetriDish(ByVal Sample As String) As BitArray
Dim PetriDish As New BitArray(Sample.Length)
Dim dead As Boolean = True
 
For i As Integer = 0 To Sample.Length - 1
Select Case Sample.Substring(i, 1)
Case "1", "#"
PetriDish(i) = True
dead = False
Case "0", "_"
PetriDish(i) = False
Case Else
Throw New Exception("Illegal value in string position " & i)
Return Nothing
End Select
Next
 
If dead Then
Throw New Exception("Entered sample is dead.")
Return Nothing
End If
 
Return PetriDish
End Function
 
Private Function GetNextGeneration(ByRef PetriDish As BitArray) As PetriStatus
Dim petriCache = New BitArray(PetriDish.Length)
Dim neighbours As Integer
Dim stable As Boolean = True
Dim dead As Boolean = True
 
For i As Integer = 0 To PetriDish.Length - 1
neighbours = 0
If i > 0 AndAlso PetriDish(i - 1) Then neighbours += 1
If i < PetriDish.Length - 1 AndAlso PetriDish(i + 1) Then neighbours += 1
 
petriCache(i) = (PetriDish(i) And neighbours = 1) OrElse (Not PetriDish(i) And neighbours = 2)
If PetriDish(i) <> petriCache(i) Then stable = False
If petriCache(i) Then dead = False
Next
 
PetriDish = petriCache
 
If dead Then Return PetriStatus.Dead
If stable Then Return PetriStatus.Stable
Return PetriStatus.Active
 
End Function
 
Private Function BuildDishString(ByVal PetriDish As BitArray) As String
Dim sw As New StringBuilder()
For Each b As Boolean In PetriDish
sw.Append(IIf(b, "#", "_"))
Next
 
Return sw.ToString()
End Function
End Module</lang>
 
Output:
<pre>C:\>CellularAutomata _###_##_#_#_#_#__#__
000: _###_##_#_#_#_#__#__
001: _#_#####_#_#_#______
002: __##___##_#_#_______
003: __##___###_#________
004: __##___#_##_________
005: __##____###_________
006: __##____#_#_________
007: __##_____#__________
008: __##________________
Sample stable after 8 generations.</pre>
 
=={{header|Wart}}==
===Simple===
<langsyntaxhighlight lang="python">def (gens n l)
prn l
repeat n
Line 3,180 ⟶ 5,929:
def (next a b c) # next state of b given neighbors a and c
if (and a c) not.b
(or a c) b</langsyntaxhighlight>
 
Output looks a little ugly:
Line 3,197 ⟶ 5,946:
Computing the next generation becomes much cleaner once you invest a few LoC in a new datatype.
 
<langsyntaxhighlight lang="python">def (uca l) # new datatype: unidimUni-dimensional Cellular CAAutomaton
(tag uca (list l len.l))
 
Line 3,203 ⟶ 5,952:
rep.l.1
 
defcoerce uca list # convertinghow to convert it to a list
(fn(_) rep._.0)
 
Line 3,228 ⟶ 5,977:
def (next a b c)
if (and a c) not.b
(or a c) b</langsyntaxhighlight>
 
Output is prettier now:
Line 3,246 ⟶ 5,995:
__##________________
__##________________</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
<syntaxhighlight lang="wren">var trans = "___#_##_"
 
var v = Fn.new { |cell, i| (cell[i] != "_") ? 1 : 0 }
 
var evolve = Fn.new { |cell, backup|
var len = cell.count - 2
var diff = 0
for (i in 1...len) {
/* use left, self, right as binary number bits for table index */
backup[i] = trans[v.call(cell, i - 1) * 4 + v.call(cell, i) * 2 + v.call(cell, i + 1)]
diff = diff + ((backup[i] != cell[i]) ? 1 : 0)
}
cell.clear()
cell.addAll(backup)
return diff != 0
}
 
var c = "_###_##_#_#_#_#__#__".toList
var b = "____________________".toList
while(true) {
System.print(c[1..-1].join())
if (!evolve.call(c,b)) break
}</syntaxhighlight>
 
{{out}}
<pre>
###_##_#_#_#_#__#__
#_#####_#_#_#______
_##___##_#_#_______
_##___###_#________
_##___#_##_________
_##____###_________
_##____#_#_________
_##_____#__________
_##________________
</pre>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">code ChOut=8, CrLf=9;
int Gen, Now, New, I;
[Now:= $076A_A400;
Line 3,259 ⟶ 6,047:
Now:= New;
];
]</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
_____###_##_#_#_#_#__#__________
Line 3,273 ⟶ 6,061:
______##________________________
______##________________________
</pre>
 
=={{header|zkl}}==
{{trans|Groovy}}
<syntaxhighlight lang="zkl">fcn life1D(line){
right:=line[1,*] + False; // shift left, False fill
left :=T(False).extend(line[0,-1]); // shift right
left.zip(line,right).apply(fcn(hood){ hood.sum(0)==2 });
}</syntaxhighlight>
<syntaxhighlight lang="zkl">chars:=T("_","#");
cells:="_###_##_#_#_#_#__#__".split("").apply('==("#")); //-->L(False,True,True,True,False...)
do(10){ cells.apply(chars.get).concat().println(); cells=life1D(cells); }</syntaxhighlight>
Or, using strings instead of lists:
<syntaxhighlight lang="zkl">fcn life1D(line){
right:=line[1,*] + "_"; // shift left, "_" fill
left :="_" + line[0,-1]; // shift right
Utils.Helpers.zipWith(
fcn(a,b,c){ (String(a,b,c) - "_") == "##" and "#" or "_" },
left,line,right).concat();
}</syntaxhighlight>
<syntaxhighlight lang="zkl">cells:="_###_##_#_#_#_#__#__";
do(10){ cells.println(); cells=life1D(cells); }</syntaxhighlight>
{{out}}
<pre>
_###_##_#_#_#_#__#__
_#_#####_#_#_#______
__##___##_#_#_______
__##___###_#________
__##___#_##_________
__##____###_________
__##____#_#_________
__##_____#__________
__##________________
</pre>
9,482

edits