![](https://habrastorage.org/webt/te/am/jn/teamjnrjsy-umukoljsjepmffk4.png)
Today we will go on a colorful journey through the world of cellular automata, simultaneously studying some tricks of their implementation, and also try to understand what is hidden behind this beauty - a curious game for an idle mind or a deep philosophical concept that resonates with many models.
For practice and a better understanding, you should try to implement the following algorithms yourself. Well, if laziness, or just out of interest, you can play around with various implementations:
![](https://habrastorage.org/webt/gh/ae/ve/ghaevesccwtayeaqj_q6aj5pvmo.png)
β . , 0 1, , . . , . , . , 256 ( 8- ).
![](https://habrastorage.org/webt/dl/x9/kp/dlx9kp-outr6lvq05tnzu6nffim.gif)
, .
:
using Pkg
pkgs = ["Images", "ColorSchemes", "FFTW"]
for p in pkgs
Pkg.add(p)
end
using Images, ColorSchemes, FFTW, LinearAlgebra: kron
using Random: bitrand
cd("C:\\Users\\User\\Desktop\\Mycop")
0 255 ( ). , . , , :
function cellauto( n::Int64, m::Int64, rule::Int64, s::Int64 = 1 )
ptrn = digits(Bool, rule, base = 2, pad = 8)
bt = [ bitstring(i)[end-2:end] for i = 0:7 ]
d = Dict( bt[i] => ptrn[i] for i = 1:8 )
M = falses(n,m)
M[1,m Γ· 2] = true
for i = 1:n-1, j = 2:m-1
key = "$(M[i, j-1]*1)$(M[i, j]*1)$(M[i, j+1]*1)"
M[i+1,j] = d[key]
end
kron(M, ones(Int,s,s) )
end
M0 = cellauto(100, 200, 30, 4)
Gray.( M0 )
![](https://habrastorage.org/webt/gr/fg/-4/grfg-4t74lqe7wjl3ingd3ubevc.png)
30, . , , . , - : , β¦ , . :
Arr = cellauto.(40, 40, [0:23;], 2);
Imgs = [ Gray.(a) for a in Arr ]
reshape(Imgs, 4,6)
![](https://habrastorage.org/webt/xj/9w/dm/xj9wdmaxvdgvz3pqc3iyncq6uws.png)
, . :
![](https://habrastorage.org/webt/ng/ru/al/ngrualxkvbrdugbgtugmdttv9za.png)
![](https://habrastorage.org/webt/fe/jn/2b/fejn2bm8o_kgxxewjv4lplpzlxu.png)
Luxor, .
"" β ( ) . , , : , ( ) .
![](https://habrastorage.org/webt/lr/mr/jq/lrmrjqwj4ne2rt72--vgqkn6o-k.gif)
: , , ( !) . , , , . . . , , , , , , . "" .
, , . , , .
function makefilter(N::Int64)
filter = zeros(Complex, N, N);
IDX(x, y) = ( (x + N) % N ) + ( (y+N) % N ) * N + 1
filter[IDX(-1, -1)] = 1. ;
filter[IDX( 0, -1)] = 1. ;
filter[IDX( 1, -1)] = 1. ;
filter[IDX(-1, 0)] = 1. ;
filter[IDX( 1, 0)] = 1. ;
filter[IDX(-1, 1)] = 1. ;
filter[IDX( 0, 1)] = 1. ;
filter[IDX( 1, 1)] = 1. ;
return fft( real.(filter) )
end
function fftlife(N = 16, steps = 100, dx = 0, glider = true)
if glider
state = falses(N, N)
state[4,5] = state[5,6] = state[6,6] = true
state[6,5] = state[6,4] = true
else
state = bitrand(N, N)
end
filter = makefilter(N)
for i in 1:steps
tmp = fft( real.(state) )
tmp .*= filter
summ = ifft(tmp)
for i in eachindex(state)
t = round( Int, real(summ[i]) ) >> dx
state[i] = ( state[i] ? t == 2 || t == 3 : t == 3 )
end
save("KonLife_$(N)x$(N)_$i.png", kron( Gray.(state), ones(8,8) ) )
end
end
fftlife(16, 60)
![](https://habrastorage.org/webt/ke/sb/53/kesb53gdy-c_ve9tvi9h9o_uqce.gif)
β , ( ). , "" .
:
1 0, , , .
Initial conditionsfunction clamp(x)
y = copy(x)
y[x.>1] .= 1
y[x.<0] .= 0
y
end
function func_linear(X, a, b)
Y = [ (x-a + 0.5b)/b for x in X ]
Y[X.<a-0.5b] .= 0
Y[X.>a+0.5b] .= 1
return Y
end
function splat!(aa, ny, nx, ra)
x = round(Int, rand()*nx ) + 1
y = round(Int, rand()*ny ) + 1
c = rand() > 0.5
for dx = -ra:ra, dy = -ra:ra
ix = x+dx
iy = y+dy
if ix>=1 && ix<=nx && iy>=1 && iy<=ny
aa[iy,ix] = c
end
end
end
function initaa(ny, nx, ra)
aa = zeros(ny, nx)
for t in 0:((nx/ra)*(ny/ra))
splat!(aa, ny, nx, ra);
end
aa
end
Sigmoidfunc_smooth(x::Float64, a, b) = 1 / ( 1 + exp(-4(x-a)/b) )
sigmoid_a(x, a, ea) = func_smooth(x, a, ea)
sigmoid_b(x, b, eb) = 1 - sigmoid_a(x, b, eb)
sigmoid_ab(x, a, b, ea, eb) = sigmoid_a(x, a, ea) * sigmoid_b(x, b, eb)
sigmoid_mix(x, y, m, em) = x - x * func_smooth(m, 0.5, em) + y * func_smooth(m, 0.5, em)
function snm(N, M, en, em, b1, b2, d1, d2)
[ sigmoid_mix( sigmoid_ab(N[i,j], b1, b2, en, en),
sigmoid_ab(N[i,j], d1, d2, en, en), M[i,j], em )
for i = 1:size(N, 1), j = 1:size(N, 2) ]
end
Main functionfunction smoothlife(NX = 128, NY = 128, tfin = 10, scheme = 1)
function derivative(aa)
aaf = fft(aa)
nf = aaf .* krf
mf = aaf .* kdf
n = real.(ifft(nf)) / kflr
m = real.(ifft(mf)) / kfld
2snm(n, m, alphan, alpham, b1, b2, d1, d2) .- 1
end
ra = 10
ri = ra/3
b = 1
b1 = 0.257
b2 = 0.336
d1 = 0.365
d2 = 0.551
alphan = 0.028
alpham = 0.147
kd = zeros(NY,NX)
kr = zeros(NY,NX)
aa = zeros(NY,NX)
x = [ j - 1 - NX/2 for i=1:NY, j=1:NX ]
y = [ i - 1 - NY/2 for i=1:NY, j=1:NX ]
r = sqrt.(x.^2 + y.^2)
kd = 1 .- func_linear(r, ri, b)
kr = func_linear(r, ri, b) .* ( 1 .- func_linear(r, ra, b) )
kflr = sum(kr)
kfld = sum(kd)
krf = fft(fftshift(kr))
kdf = fft(fftshift(kd))
for td = 64
aa = initaa(NY,NX,ra)
dt = 1/td;
l = 0
nx = 0
for t = 0:dt:tfin
if scheme==1
aa += dt*derivative(aa)
elseif scheme==2
da = derivative(aa);
aa1 = clamp(aa + dt*da)
for h = 0:20
alt = aa1
aa1 = clamp(aa + dt*(da + derivative(aa1))/2)
if maximum(abs.(alt-aa1))<1e-8
break
end
end
aa = copy(aa1)
elseif scheme==3
n0 = 1+mod(l,3)
n1 = 1+mod(l-1,3)
n2 = 1+mod(l-2,3)
f = zeros(NY, NX, 3)
f[:,:,n0] = derivative(aa)
if l==0
aa += dt*f[:,:,n0]
elseif l==1
aa += dt*(3*f[:,:,n0] - f[:,:,n1])/2
elseif l>=2
aa += dt*(23*f[:,:,n0] - 16*f[:,:,n1] + 5*f[:,:,n2])/12
end
elseif scheme==4
k1 = derivative(aa)
k2 = derivative(clamp(aa + dt/2*k1))
k3 = derivative(clamp(aa + dt/2*k2))
k4 = derivative(clamp(aa + dt*k3))
aa += dt*(k1 + 2*k2 + 2*k3 + k4)/6
end
aa = clamp(aa)
if t >= nx
save("$(scheme)\\$(td)_$t.png", Gray.(kron(aa, ones(2, 2) ) ) )
nx += 1;
end
l += 1;
end
end
end
@time smoothlife(256, 256, 20, 3)
![](https://habrastorage.org/webt/y6/ve/ol/y6veolr14pmra6qkmhg2ntjobd8.gif)
, . , . .
![](https://habrastorage.org/webt/lp/yj/yn/lpyjynzsj-7mo_flncaimu3h7rc.png)
β , , . β .
![](https://habrastorage.org/webt/yr/tt/sp/yrttspeh1ykrudvpwoqev6yrrsk.gif)
, , , :
- β , , .
- β , , .
rosetta code , :
function ant(width, height)
y, x = fld(height, 2), fld(width, 2)
M = trues(height, width)
dir = im
for i in 0:1000000
x in 1:width && y in 1:height || break
dir *= M[y, x] ? im : -im
M[y, x] = !M[y, x]
x, y = reim(x + im * y + dir)
i%100==0 && save("LR//zLR_$i.png", Gray.( kron(M,ones(4,4) ) ) )
end
Gray.(M)
end
ant(100, 100)
![](https://habrastorage.org/webt/p_/rt/b2/p_rtb2uiqvman80izhhh8v7j7eo.gif)
, . β . !
:
function ant(width, height, comnds;
steps = 10, cxema = reverse(ColorSchemes.hot),
savevery = 100, pixfactor = 20)
ma3x2pix() = [ clrs[k%n+1] for k in M ]
bigpix() = kron( ma3x2pix(), ones(Int64,m,m) )
save2pix(i) = save("$(comnds)_$i.png", bigpix() )
m = pixfactor
n = length(comnds)
colorsinscheme = length(cxema)
M = zeros(Int64, height, width)
y, x = fld(height, 2), fld(width, 2)
st = colorsinscheme Γ· n
clrs = [ cxema.colors[i] for i in 1:st:colorsinscheme ]
dir = im
for i in 0:steps
x in 1:width && y in 1:height || (save2pix(i); break)
j = M[y, x] % n + 1
dir *= comnds[j] == 'L' ? -im : im
M[y, x] += 1
x, y = reim(x + im * y + dir)
i % savevery==0 && save2pix(i)
end
ma3x2pix()
end
@time ant(16, 16, "LLRR", steps = 100, savevery = 1, pixfactor = 20)
![](https://habrastorage.org/webt/et/6h/jn/et6hjnqf3m29aykxeobexdpn1zu.gif)
, !
![](https://habrastorage.org/webt/rg/0x/yx/rg0xyxvt9xhuuuaoasn8qkazcqo.png)
![LLRR](https://habrastorage.org/webt/nt/de/_o/ntde_oisuiixl1twfhr8x97zpty.png)
. , ? ?..
function hsv2rgb(h, s, v)
c = v * s
x = c * (1 - abs(((h/60) % 2) - 1) )
m = v - c
r,g,b =
if h < 60
(c, x, 0)
elseif h < 120
(x, c, 0)
elseif h < 180
(0, c, x)
elseif h < 240
(0, x, c)
elseif h < 300
(x, 0, c)
else
(c, 0, x)
end
(r + m), (b + m), (g + m)
end
function mandelbrot()
w, h = 1000, 1000
zoom = 1.0
moveX = 0
moveY = 0
img = Array{RGB{Float64}, 2}(undef,h, w)
maxIter = 30
for x in 1:w
for y in 1:h
i = maxIter
c = Complex(
(2*x - w) / (w * zoom) + moveX,
(2*y - h) / (h * zoom) + moveY
)
z = c
while abs(z) < 2 && (i -= 1) > 0
z = z^2 + c
end
r,g,b = hsv2rgb(i / maxIter * 360, 1, i / maxIter)
img[y,x] = RGB{Float64}(r, g, b)
end
end
save("mandelbrot_set2.png", img)
end
mandelbrot()
![](https://habrastorage.org/webt/o5/st/aw/o5stawfnqjqf-r4zpmjmrsqmy6c.png)
:
![RRRLRRLRRR](https://habrastorage.org/webt/bs/no/_r/bsno_rewy0dfkweszbx3xabsxps.gif)
![RRRLR9000000](https://habrastorage.org/webt/uo/wr/_t/uowr_tzhcvqmjnwj7hhmsuxgiau.png)
![RRLRLLRRRRLL](https://habrastorage.org/webt/ay/jf/aw/ayjfawjzlx8nimlymcpqftfykrq.png)
![RRLR](https://habrastorage.org/webt/1d/hk/jv/1dhkjvggxwrlocttcby8k_v0cy4.png)
![RRLLLRLRL](https://habrastorage.org/webt/ex/w3/cw/exw3cwl-4myadqggc_jaavcbzvw.gif)
![RRLLLRLLLRLL](https://habrastorage.org/webt/8e/ww/z1/8ewwz1qic3bzjhfjikgahfdx2ay.gif)
![RRLLLRLLLLL_200000000](https://habrastorage.org/webt/ig/dr/8m/igdr8mjhbkul6_w-0eshjq404ec.png)
β . :
![RRLLLL30_000_000_000](https://habrastorage.org/webt/iw/s5/zi/iws5zizcf0ivtoir7xjkz3mbryk.png)
![Rllr](https://habrastorage.org/webt/pn/t-/_4/pnt-_4onnrt7tegrrnlfu7qr3u0.gif)
![RLLLLRRRLLL](https://habrastorage.org/webt/2i/tr/10/2itr10tcx17jwv_3wxb01snicko.gif)
![RLLLLLLLRRL](https://habrastorage.org/webt/ey/lu/8b/eylu8bwkpa0df819caufdoncd-a.gif)
![LLRLLLL](https://habrastorage.org/webt/_p/bx/dz/_pbxdzqv8psp9o6wzomp48rf_-u.gif)
, . (-), -, , , ! , !
. ,
![](https://habrastorage.org/webt/qk/4x/-h/qk4x-hswl62dg3lewaxqah9qzis.gif)
, . ( - . )
The topic of cellular automata with the growth of computing power and improvement of algorithms is becoming more popular. Wolframβs blog has a small report on this topic, and everyone can see for himself - there are a lot of articles, the most varied: there are friendships with neural networks, random number generators, quantum dots, compression, and much more ...
And finally, the self-copying structure created by Ted Codd to argue for a pint of beer
![](https://habrastorage.org/webt/bd/jj/wv/bdjjwvjyolkqdtpdr414jjnlgfg.gif)