You can generate a cellular automaton using the ca
function, specifying the Wolfram rule. For example:
The number of rows to be generated are specified with the
steps
parameter in the ca()
function.
The length of the cellular automaton can be specified with the
ncols
parameter in the ca()
function. See
below how to specify arbitrary initial states.
You can get an animation of a cellular automaton using
plot(animate = TRUE)
:
You can get the visual representation of the definition of a rule
with wolfram_rule_def()
:
The first line in each box is a possible input, and the second line is the output of the function. For example, Rule 30 is defined as:
111 -> 0
110 -> 0
101 -> 0
100 -> 1
011 -> 1
010 -> 1
001 -> 1
000 -> 0
The function wolfram_rule()
gives the output of the rule
as a numeric vector:
To generate multiple plots in one go, you can wrap the
ca(rule) |> plot()
inside a purrr::map()
call and then pipe the resulting list into
patchwork::wrap_plots()
.
For example, you can generate a preview of all the 256 rules this way:
all_rules <- purrr::map(0:255, \(rule){
ca(rule,
ncols = 30,
steps = 30) |>
plot()
}) |>
patchwork::wrap_plots(nrow = 32)
ggplot2::ggsave("all-cellular-automata.png",
plot = all_rules,
width = 12,
height = 48)
This will create a long png file with all the rules.
You can define how long the cellular automaton line is using the
ncols
parameter in the ca()
function.
Alternatively, you can define an arbitrary initial state, which will
determine how long the line is.
By default, the initial state has a single filled cell in the middle
of an empty row. You can specify different initial states using the
initialstate
parameter in the ca()
function.
The initialstate
needs to be a vector of 0s and 1s. When
you specify the initialstate
, the ncols
is
calculated as length(initialstate)
.
For example, here we are running Rule 30 for 10 steps from several random initial states:
# sample rule 30 from different random starting points
purrr::map(1:25, \(i){
ca(30,
initialstate = sample(c(0, 1), size = 10, replace = TRUE),
steps = 10) |>
plot(title = NULL)
}) |>
patchwork::wrap_plots()
The function sample(c(0, 1), size = 10, replace = TRUE)
generates a random vector of 0s and 1s of length 10.
By default the line is wrapped around, meaning it is actually a circle, with the end connected to the beginning.
You can turn off wrapping with wrap = FALSE
in the
ca()
function, which will keep the first and the last cells
always empty.
Given the circular default, you can also plot the cellular automaton
in polar coordinates, adding the circle = TRUE
option to
plot()
. To make the time flow from the center to the outer
edges, set time_flow = "up"
as well.
This also works for animations: