Elementary cellular automaton/Infinite length: Difference between revisions
Content deleted Content added
m →{{header|Wren}}: Minor tidy |
|||
(31 intermediate revisions by 15 users not shown) | |||
Line 1:
{{
The purpose of this task is to create a version of an [[Elementary cellular automaton]] whose number of cells is only limited by the memory size of the computer.
Line 14:
More complex methods can be imagined, provided it is possible to somehow encode the infinite sections. But for this task we will stick to this simple version.
=={{header|11l}}==
{{trans|Nim}}
<syntaxhighlight lang="11l">F step(cells, rule)
V result = ‘’
L(i) 0 .< cells.len - 2
V bin = 0
V b = 2
L(n) i .< i + 3
bin += Int(cells[n] == ‘*’) << b
b >>= 1
V a = I (rule [&] (1 << bin)) != 0 {‘*’} E ‘.’
result ‘’= a
R result
F addNoCells(&cells)
V left = I cells[0] == ‘*’ {‘.’} E ‘*’
V right = I cells.last == ‘*’ {‘.’} E ‘*’
cells = left‘’cells‘’right
cells = left‘’cells‘’right
F evolve(limit, rule)
print(‘Rule #’rule)
V cells = ‘*’
L 0 .< limit
addNoCells(&cells)
V width = 40 + (cells.len >> 1)
print(cells.rjust(width))
cells = step(cells, rule)
evolve(35, 90)</syntaxhighlight>
{{out}}
<pre>
Rule #90
..*..
..*.*..
..*...*..
..*.*.*.*..
..*.......*..
..*.*.....*.*..
..*...*...*...*..
..*.*.*.*.*.*.*.*..
..*...............*..
..*.*.............*.*..
..*...*...........*...*..
..*.*.*.*.........*.*.*.*..
..*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................*..
..*.*.............................*.*..
..*...*...........................*...*..
..*.*.*.*.........................*.*.*.*..
..*.......*.......................*.......*..
..*.*.....*.*.....................*.*.....*.*..
..*...*...*...*...................*...*...*...*..
..*.*.*.*.*.*.*.*.................*.*.*.*.*.*.*.*..
..*...............*...............*...............*..
..*.*.............*.*.............*.*.............*.*..
..*...*...........*...*...........*...*...........*...*..
..*.*.*.*.........*.*.*.*.........*.*.*.*.........*.*.*.*..
..*.......*.......*.......*.......*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................................................*..
..*.*.............................................................*.*..
..*...*...........................................................*...*..
</pre>
=={{header|C++}}==
<
#include <iostream>
#include <iomanip>
Line 58 ⟶ 130:
return 0;
}
</syntaxhighlight>
{{out}}
<pre>
Line 91 ⟶ 163:
=={{header|D}}==
{{trans|Python}}
<
std.algorithm;
alias R = replicate;
Line 115 ⟶ 187:
}
}
}</
The output is the same as the Python entry.
=={{header|Elixir}}==
{{works with|Elixir|1.3}}
{{trans|Ruby}}
<syntaxhighlight lang="elixir">
defmodule Elementary_cellular_automaton do
def infinite(cell, rule, times) do
each(cell, rule_pattern(rule), times)
end
defp each(_, _, 0), do: :ok
defp each(cells, rules, times) do
IO.write String.duplicate(" ", times)
IO.puts String.replace(cells, "0", ".") |> String.replace("1", "#")
c = not_cell(String.first(cells)) <> cells <> not_cell(String.last(cells))
next_cells = Enum.map_join(0..String.length(cells)+1, fn i ->
Map.get(rules, String.slice(c, i, 3))
end)
each(next_cells, rules, times-1)
end
defp not_cell("0"), do: "11"
defp not_cell("1"), do: "00"
defp rule_pattern(rule) do
list = Integer.to_string(rule, 2) |> String.pad_leading(8, "0")
|> String.codepoints |> Enum.reverse
Enum.map(0..7, fn i -> Integer.to_string(i, 2) |> String.pad_leading(3, "0") end)
|> Enum.zip(list) |> Map.new
end
end
Enum.each([18, 30], fn rule ->
IO.puts "\nRule : #{rule}"
Elementary_cellular_automaton.infinite("1", rule, 25)
end)</syntaxhighlight>
{{out}}
<pre>
Rule : 18
#
#.#
#...#
#.#.#.#
#.......#
#.#.....#.#
#...#...#...#
#.#.#.#.#.#.#.#
#...............#
#.#.............#.#
#...#...........#...#
#.#.#.#.........#.#.#.#
#.......#.......#.......#
#.#.....#.#.....#.#.....#.#
#...#...#...#...#...#...#...#
#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#
#...............................#
#.#.............................#.#
#...#...........................#...#
#.#.#.#.........................#.#.#.#
#.......#.......................#.......#
#.#.....#.#.....................#.#.....#.#
#...#...#...#...................#...#...#...#
#.#.#.#.#.#.#.#.................#.#.#.#.#.#.#.#
#...............#...............#...............#
Rule : 30
#
###
##..#
##.####
##..#...#
##.####.###
##..#....#..#
##.####..######
##..#...###.....#
##.####.##..#...###
##..#....#.####.##..#
##.####..##.#....#.####
##..#...###..##..##.#...#
##.####.##..###.###..##.###
##..#....#.###...#..###..#..#
##.####..##.#..#.#####..#######
##..#...###..####.#....###......#
##.####.##..###....##..##..#....###
##..#....#.###..#..##.###.####..##..#
##.####..##.#..######..#...#...###.####
##..#...###..####.....####.###.##...#...#
##.####.##..###...#...##....#...#.#.###.###
##..#....#.###..#.###.##.#..###.##.#.#...#..#
##.####..##.#..###.#...#..####...#..#.##.######
##..#...###..####...##.#####...#.#####.#..#.....#
</pre>
=={{header|Go}}==
{{trans|C++}}
<syntaxhighlight lang="go">package main
import (
"fmt"
"strings"
)
func btoi(b bool) int {
if b {
return 1
}
return 0
}
func evolve(l, rule int) {
fmt.Printf(" Rule #%d:\n", rule)
cells := "O"
for x := 0; x < l; x++ {
cells = addNoCells(cells)
width := 40 + (len(cells) >> 1)
fmt.Printf("%*s\n", width, cells)
cells = step(cells, rule)
}
}
func step(cells string, rule int) string {
newCells := new(strings.Builder)
for i := 0; i < len(cells)-2; i++ {
bin := 0
b := uint(2)
for n := i; n < i+3; n++ {
bin += btoi(cells[n] == 'O') << b
b >>= 1
}
a := '.'
if rule&(1<<uint(bin)) != 0 {
a = 'O'
}
newCells.WriteRune(a)
}
return newCells.String()
}
func addNoCells(cells string) string {
l, r := "O", "O"
if cells[0] == 'O' {
l = "."
}
if cells[len(cells)-1] == 'O' {
r = "."
}
cells = l + cells + r
cells = l + cells + r
return cells
}
func main() {
for _, r := range []int{90, 30} {
evolve(25, r)
fmt.Println()
}
}</syntaxhighlight>
{{out}}
<pre>
Rule #90:
..O..
..O.O..
..O...O..
..O.O.O.O..
..O.......O..
..O.O.....O.O..
..O...O...O...O..
..O.O.O.O.O.O.O.O..
..O...............O..
..O.O.............O.O..
..O...O...........O...O..
..O.O.O.O.........O.O.O.O..
..O.......O.......O.......O..
..O.O.....O.O.....O.O.....O.O..
..O...O...O...O...O...O...O...O..
..O.O.O.O.O.O.O.O.O.O.O.O.O.O.O.O..
..O...............................O..
..O.O.............................O.O..
..O...O...........................O...O..
..O.O.O.O.........................O.O.O.O..
..O.......O.......................O.......O..
..O.O.....O.O.....................O.O.....O.O..
..O...O...O...O...................O...O...O...O..
..O.O.O.O.O.O.O.O.................O.O.O.O.O.O.O.O..
..O...............O...............O...............O..
Rule #30:
..O..
..OOO..
..OO..O..
..OO.OOOO..
..OO..O...O..
..OO.OOOO.OOO..
..OO..O....O..O..
..OO.OOOO..OOOOOO..
..OO..O...OOO.....O..
..OO.OOOO.OO..O...OOO..
..OO..O....O.OOOO.OO..O..
..OO.OOOO..OO.O....O.OOOO..
..OO..O...OOO..OO..OO.O...O..
..OO.OOOO.OO..OOO.OOO..OO.OOO..
..OO..O....O.OOO...O..OOO..O..O..
..OO.OOOO..OO.O..O.OOOOO..OOOOOOO..
..OO..O...OOO..OOOO.O....OOO......O..
..OO.OOOO.OO..OOO....OO..OO..O....OOO..
..OO..O....O.OOO..O..OO.OOO.OOOO..OO..O..
..OO.OOOO..OO.O..OOOOOO..O...O...OOO.OOOO..
..OO..O...OOO..OOOO.....OOOO.OOO.OO...O...O..
..OO.OOOO.OO..OOO...O...OO....O...O.O.OOO.OOO..
..OO..O....O.OOO..O.OOO.OO.O..OOO.OO.O.O...O..O..
..OO.OOOO..OO.O..OOO.O...O..OOOO...O..O.OO.OOOOOO..
..OO..O...OOO..OOOO...OO.OOOOO...O.OOOOO.O..O.....O..
</pre>
=={{header|Haskell}}==
Infinite lists are natural in Haskell, however the task forces us to deal with lists that are infinite in both directions. These structures could be efficiently implemented as a ''zipper lists''. Moreover, zipper lists are instances of magic <code>Comonad</code> class, which gives beautifull implementation of cellular automata.
This solution is kinda involved, but it is guaranteed to be total and correct by type checker.
First we provide the datatype, the viewer and constructor:
<syntaxhighlight lang="haskell">{-# LANGUAGE DeriveFunctor #-}
import Control.Comonad
import Data.InfList (InfList (..), (+++))
import qualified Data.InfList as Inf
data Cells a = Cells (InfList a) a (InfList a) deriving Functor
view n (Cells l x r) = reverse (Inf.take n l) ++ [x] ++ (Inf.take n r)
fromList [] = fromList [0]
fromList (x:xs) = let zeros = Inf.repeat 0
in Cells zeros x (xs +++ zeros)</syntaxhighlight>
In order to run the CA on the domain we make it an instance of <code>Comonad</code> class. Running the CA turns to be just an iterative comonadic ''extension'' of the rule:
<syntaxhighlight lang="haskell">instance Comonad Cells where
extract (Cells _ x _) = x
duplicate x = Cells (rewind left x) x (rewind right x)
where
rewind dir = Inf.iterate dir . dir
right (Cells l x (r ::: rs)) = Cells (x ::: l) r rs
left (Cells (l ::: ls) x r) = Cells ls l (x ::: r)
runCA rule = iterate (=>> step)
where step (Cells (l ::: _) x (r ::: _)) = rule l x r</syntaxhighlight>
Following is the rule definition and I/O routine:
<syntaxhighlight lang="haskell">rule n l x r = n `div` (2^(4*l + 2*x + r)) `mod` 2
displayCA n w rule init = mapM_ putStrLn $ take n result
where result = fmap display . view w <$> runCA rule init
display 0 = ' '
display _ = '*'</syntaxhighlight>
{{Out}}
<pre>λ> displayCA 30 20 (rule 90) (fromList [1])
*
* *
* *
* * * *
* *
* * * *
* * * *
* * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * * * *
* * * * * * * *
* * * * * * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * *
* * * * * *
* * * * * *
* * * * * * * * * * * *
* *
* * * *
* * * *
* * * * * * * *
* * * * * *
* * * * * * * * * * </pre>
See also [[Elementary cellular automaton#Haskell]]
=={{header|J}}==
Line 129 ⟶ 494:
Implementation:
<
trim=: |.@(}.~ ] i. 1-{.)^:2
next=: trim@(((8$2) #: [) {~ 2 #. 1 - [: |: |.~"1 0&_1 0 1@]) ext9</
In other words, a wrapped version of the [[Elementary_cellular_automaton#J|original implementation]].
Line 137 ⟶ 502:
example use:
<
*
* *
Line 146 ⟶ 511:
* * * *
* * * * * * * *
* *</
Looks like a [[Sierpinski_triangle|Sierpinski triangle]]
=={{header|Java}}==
<syntaxhighlight lang="java">
public final class ElementaryCellularAutomatonInfiniteLength {
public static void main(String[] aArgs) {
evolve(35, 90);
System.out.println();
}
private static void evolve(int aLimit, int aRule) {
System.out.println(" Rule# " + aRule);
StringBuilder cells = new StringBuilder(Character.toString(STAR));
for ( int i = 0; i < aLimit; i++ ) {
addCells(cells);
final int width = 40 - ( cells.length() >> 1 );
System.out.println(" ".repeat(width) + cells);
cells = nextStep(cells, aRule);
}
}
private static void addCells(StringBuilder aCells) {
final char left = ( aCells.charAt(0) == STAR ) ? DOT : STAR;
final char right = ( aCells.charAt(aCells.length() - 1 ) == STAR ) ? DOT : STAR;
for ( int i = 0; i < 2; i++ ) {
aCells.insert(0, left);
aCells.append(right);
}
}
private static StringBuilder nextStep(StringBuilder aCells, int aRule) {
StringBuilder nextCells = new StringBuilder();
for ( int i = 0; i < aCells.length() - 2; i++ ) {
int binary = 0;
int shift = 2;
for ( int j = i; j < i + 3; j++ ) {
binary += ( ( aCells.charAt(j) == STAR ) ? 1 : 0 ) << shift;
shift >>= 1;
}
final char symbol = ( ( aRule & ( 1 << binary ) ) == 0 ) ? DOT : STAR;
nextCells.append(symbol);
}
return nextCells;
}
private static final char DOT = '.';
private static final char STAR = '*';
}
</syntaxhighlight>
{{ out }}
<pre>
Rule# 90
..*..
..*.*..
..*...*..
..*.*.*.*..
..*.......*..
..*.*.....*.*..
..*...*...*...*..
..*.*.*.*.*.*.*.*..
..*...............*..
..*.*.............*.*..
..*...*...........*...*..
..*.*.*.*.........*.*.*.*..
..*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................*..
..*.*.............................*.*..
..*...*...........................*...*..
..*.*.*.*.........................*.*.*.*..
..*.......*.......................*.......*..
..*.*.....*.*.....................*.*.....*.*..
..*...*...*...*...................*...*...*...*..
..*.*.*.*.*.*.*.*.................*.*.*.*.*.*.*.*..
..*...............*...............*...............*..
..*.*.............*.*.............*.*.............*.*..
..*...*...........*...*...........*...*...........*...*..
..*.*.*.*.........*.*.*.*.........*.*.*.*.........*.*.*.*..
..*.......*.......*.......*.......*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................................................*..
..*.*.............................................................*.*..
..*...*...........................................................*...*..
</pre>
=={{header|jq}}==
'''Adapted from [[#Python|Python]]'''
{{works with|jq}}
'''Works with gojq, the Go implementation of jq'''
'''Preliminaries'''
<syntaxhighlight lang="jq">
def lpad($len; $fill): tostring | ($len - length) as $l | ($fill * $l)[:$l] + .;
def lpad($len): lpad($len; " ");
# Like *ix `tr` but it is as though $to is padded with blanks
def tr($from;$to):
explode as $s
| ($from | explode) as $f
| ($to | explode) as $t
| reduce range(0;length) as $i ([];
($f | index($s[$i])) as $ix
| if $ix then . + [$t[$ix] // " "]
else . + [$s[$i]]
end )
| implode;
# Input: a non-negative integer
# Output: the corresponding stream of bits (0s and 1s),
# least significant digit first, with a final 0
def stream:
recurse(if . > 0 then ./2|floor else empty end) | . % 2 ;
# input: an array, e.g. as produced by [7|stream]
# output: the corresponding binary string
def to_b: reverse | map(tostring) | join("") | sub("^0";"");</syntaxhighlight>
'''The Cellular Automaton'''
<syntaxhighlight lang="jq"># Output: an unbounded stream of the form [count, row]
# giving the rows produced by the eca defined by
# $cells (a string) and $rule (an integer)
def eca_infinite($cells; $rule):
def notcell: tr("01";"10") ;
def rule2hash($rule):
[$rule | stream] as $r
| reduce range(0;8) as $i ({};
. + { ($i|[stream]|to_b|lpad(3;"0")): ($r[$i] // 0)});
rule2hash($rule) as $neighbours2next
| [0, $cells],
foreach range(1; infinite) as $i ({c: $cells};
.c = (.c[0:1]|notcell)*2 + .c + (.c[-1:]|notcell)*2 # Extend and pad the ends
| .c = ([range(1; .c|length - 1) as $i | $neighbours2next[.c[$i-1:$i+2] ]] | join(""));
[$i, .c] ) ;
</syntaxhighlight>
'''The Task'''
<syntaxhighlight lang="jq"># $lines specifies the number of lines to display for each eca
def main($lines):
(90, 30) as $rule
| "\nRule: \($rule)",
(limit($lines; eca_infinite("1"; $rule)
| .[0] as $line
| ($line|lpad(3)) + " " * ($lines - $line) + (.[1] | tr("01"; ".#") )));
main(25)</syntaxhighlight>
{{out}}
As for [[#Python|Python]].
=={{header|Julia}}==
{{trans|Python}}
<syntaxhighlight lang="julia">function ecainfinite(cells, rule, n)
notcell(cell) = (cell == '1') ? '0' : '1'
rulebits = reverse(string(rule, base = 2, pad = 8))
neighbors2next = Dict(string(n - 1, base=2, pad=3) => rulebits[n] for n in 1:8)
ret = String[]
for i in 1:n
push!(ret, cells)
cells = notcell(cells[1])^2 * cells * notcell(cells[end])^2 # Extend/pad ends
cells = join([neighbors2next[cells[i:i+2]] for i in 1:length(cells)-2], "")
end
ret
end
function testinfcells(lines::Integer)
for rule in [90, 30]
println("\nRule: $rule ($(string(rule, base = 2, pad = 8)))")
s = ecainfinite("1", rule, lines)
for i in 1:lines
println("$i: ", " "^(lines - i), replace(replace(s[i], "0" => "."), "1" => "#"))
end
end
end
testinfcells(25)
</syntaxhighlight>{{out}}
<pre>
Rule: 90 (01011010)
1: #
2: #.#
3: #...#
4: #.#.#.#
5: #.......#
6: #.#.....#.#
7: #...#...#...#
8: #.#.#.#.#.#.#.#
9: #...............#
10: #.#.............#.#
11: #...#...........#...#
12: #.#.#.#.........#.#.#.#
13: #.......#.......#.......#
14: #.#.....#.#.....#.#.....#.#
15: #...#...#...#...#...#...#...#
16: #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#
17: #...............................#
18: #.#.............................#.#
19: #...#...........................#...#
20: #.#.#.#.........................#.#.#.#
21: #.......#.......................#.......#
22: #.#.....#.#.....................#.#.....#.#
23: #...#...#...#...................#...#...#...#
24: #.#.#.#.#.#.#.#.................#.#.#.#.#.#.#.#
25: #...............#...............#...............#
Rule: 30 (00011110)
1: #
2: ###
3: ##..#
4: ##.####
5: ##..#...#
6: ##.####.###
7: ##..#....#..#
8: ##.####..######
9: ##..#...###.....#
10: ##.####.##..#...###
11: ##..#....#.####.##..#
12: ##.####..##.#....#.####
13: ##..#...###..##..##.#...#
14: ##.####.##..###.###..##.###
15: ##..#....#.###...#..###..#..#
16: ##.####..##.#..#.#####..#######
17: ##..#...###..####.#....###......#
18: ##.####.##..###....##..##..#....###
19: ##..#....#.###..#..##.###.####..##..#
20: ##.####..##.#..######..#...#...###.####
21: ##..#...###..####.....####.###.##...#...#
22: ##.####.##..###...#...##....#...#.#.###.###
23: ##..#....#.###..#.###.##.#..###.##.#.#...#..#
24: ##.####..##.#..###.#...#..####...#..#.##.######
25: ##..#...###..####...##.#####...#.#####.#..#.....#
</pre>
=={{header|Kotlin}}==
{{trans|C++}}
<syntaxhighlight lang="scala">// version 1.1.51
fun evolve(l: Int, rule: Int) {
println(" Rule #$rule:")
var cells = StringBuilder("*")
for (x in 0 until l) {
addNoCells(cells)
val width = 40 + (cells.length shr 1)
println(cells.padStart(width))
cells = step(cells, rule)
}
}
fun step(cells: StringBuilder, rule: Int): StringBuilder {
val newCells = StringBuilder()
for (i in 0 until cells.length - 2) {
var bin = 0
var b = 2
for (n in i until i + 3) {
bin += (if (cells[n] == '*') 1 else 0) shl b
b = b shr 1
}
val a = if ((rule and (1 shl bin)) != 0) '*' else '.'
newCells.append(a)
}
return newCells
}
fun addNoCells(s: StringBuilder) {
val l = if (s[0] == '*') '.' else '*'
val r = if (s[s.length - 1] == '*') '.' else '*'
repeat(2) {
s.insert(0, l)
s.append(r)
}
}
fun main(args: Array<String>) {
evolve(35, 90)
println()
}</syntaxhighlight>
{{out}}
<pre>
Rule #90:
..*..
..*.*..
..*...*..
..*.*.*.*..
..*.......*..
..*.*.....*.*..
..*...*...*...*..
..*.*.*.*.*.*.*.*..
..*...............*..
..*.*.............*.*..
..*...*...........*...*..
..*.*.*.*.........*.*.*.*..
..*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................*..
..*.*.............................*.*..
..*...*...........................*...*..
..*.*.*.*.........................*.*.*.*..
..*.......*.......................*.......*..
..*.*.....*.*.....................*.*.....*.*..
..*...*...*...*...................*...*...*...*..
..*.*.*.*.*.*.*.*.................*.*.*.*.*.*.*.*..
..*...............*...............*...............*..
..*.*.............*.*.............*.*.............*.*..
..*...*...........*...*...........*...*...........*...*..
..*.*.*.*.........*.*.*.*.........*.*.*.*.........*.*.*.*..
..*.......*.......*.......*.......*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................................................*..
..*.*.............................................................*.*..
..*...*...........................................................*...*..
</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
An infinite background is built-in the language:
<syntaxhighlight lang="mathematica">CellularAutomaton[18, {{1}, 0}, 15] // ArrayPlot
CellularAutomaton[30, {{1}, 0}, 15] // ArrayPlot</syntaxhighlight>
=={{header|Nim}}==
{{trans|Kotlin}}
<syntaxhighlight lang="nim">import strutils
func step(cells: string; rule: int): string =
for i in 0..(cells.len - 3):
var bin = 0
var b = 2
for n in i..(i + 2):
inc bin, ord(cells[n] == '*') shl b
b = b shr 1
let a = if (rule and 1 shl bin) != 0: '*' else: '.'
result.add(a)
func addNoCells(cells: var string) =
let left = if cells[0] == '*': "." else: "*"
let right = if cells[^1] == '*': "." else: "*"
cells.insert(left)
cells.add(right)
cells.insert(left)
cells.add(right)
proc evolve(limit, rule: int) =
echo "Rule #", rule
var cells = "*"
for _ in 0..<limit:
cells.addNoCells()
let width = 40 + cells.len shr 1
echo cells.align(width)
cells = cells.step(rule)
evolve(35, 90)</syntaxhighlight>
{{out}}
<pre>Rule #90
..*..
..*.*..
..*...*..
..*.*.*.*..
..*.......*..
..*.*.....*.*..
..*...*...*...*..
..*.*.*.*.*.*.*.*..
..*...............*..
..*.*.............*.*..
..*...*...........*...*..
..*.*.*.*.........*.*.*.*..
..*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................*..
..*.*.............................*.*..
..*...*...........................*...*..
..*.*.*.*.........................*.*.*.*..
..*.......*.......................*.......*..
..*.*.....*.*.....................*.*.....*.*..
..*...*...*...*...................*...*...*...*..
..*.*.*.*.*.*.*.*.................*.*.*.*.*.*.*.*..
..*...............*...............*...............*..
..*.*.............*.*.............*.*.............*.*..
..*...*...........*...*...........*...*...........*...*..
..*.*.*.*.........*.*.*.*.........*.*.*.*.........*.*.*.*..
..*.......*.......*.......*.......*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................................................*..
..*.*.............................................................*.*..
..*...*...........................................................*...*..</pre>
=={{header|Perl}}==
The edges of a pattern is implicitly repeating. The code will try to lineup output by padding up to 40 spaces to the left, but since the cells keep expanding, that has to end somewhere.
<
my ($rule, $
my $offset = 0;
while (1) {
my ($l, $r, $st);
$pattern =~ s/^((.)\g2*)/$2$2/
$pattern =~ s/(.)\g1*$/$1$1/
$st = $
$pattern =~ tr/01/.#/;
printf "%5d| %s%s\n", $offset, ' ' x (40 + $offset), $
$
$l x 3,
map(substr($st, $_, 3), 0 .. length($st)-3),
Line 171 ⟶ 938:
}
evolve(90, "010");</
{{out}}
<pre>
Line 188 ⟶ 955:
-13| ..#.......#.......#.......#..
---(infinite more lines snipped)---
</pre>
=={{header|Phix}}==
Uses 0-expansion either side
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<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: #0000FF;">,</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">=</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"........"</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">rule</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">18</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</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;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">r</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: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rule</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">:</span><span style="color: #008000;">'.'</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">rule</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rule</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">25</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">' '</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">((</span><span style="color: #000000;">55</span><span style="color: #0000FF;">-</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;">2</span><span style="color: #0000FF;">))&</span><span style="color: #000000;">s</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">?</span><span style="color: #000000;">l</span><span style="color: #0000FF;">:</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)]=</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">4</span>
<span style="color: #0000FF;">+</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span> <span style="color: #000000;">j</span> <span style="color: #0000FF;">]=</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">)*</span><span style="color: #000000;">2</span>
<span style="color: #0000FF;">+</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">l</span><span style="color: #0000FF;">?</span><span style="color: #000000;">1</span><span style="color: #0000FF;">:</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)]=</span><span style="color: #008000;">'#'</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'#'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">'.'</span><span style="color: #0000FF;">&</span><span style="color: #000000;">t</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">[$]=</span><span style="color: #008000;">'#'</span> <span style="color: #008080;">then</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span><span style="color: #0000FF;">&</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">t</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
" .#."
" .#.#."
" .#...#."
" .#.#.#.#."
" .#.......#."
" .#.#.....#.#."
" .#...#...#...#."
" .#.#.#.#.#.#.#.#."
" .#...............#."
" .#.#.............#.#."
" .#...#...........#...#."
" .#.#.#.#.........#.#.#.#."
" .#.......#.......#.......#."
" .#.#.....#.#.....#.#.....#.#."
" .#...#...#...#...#...#...#...#."
" .#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#."
" .#...............................#."
" .#.#.............................#.#."
" .#...#...........................#...#."
" .#.#.#.#.........................#.#.#.#."
" .#.......#.......................#.......#."
" .#.#.....#.#.....................#.#.....#.#."
" .#...#...#...#...................#...#...#...#."
" .#.#.#.#.#.#.#.#.................#.#.#.#.#.#.#.#."
" .#...............#...............#...............#."
" .#.#.............#.#.............#.#.............#.#."
</pre>
Line 193 ⟶ 1,015:
Infinite generator but only print 25 lines of each rule.
<
return '0' if c == '1' else '1'
Line 213 ⟶ 1,035:
print('\nRule: %i' % rule)
for i, c in zip(range(lines), eca_infinite('1', rule)):
print('%2i: %s%s' % (i, ' '*(lines - i), c.replace('0', '.').replace('1', '#')))</
{{out}}
Line 274 ⟶ 1,096:
Uses solution to [[Elementary cellular automaton]] saved in file "Elementary_cellular_automata.rkt"
<
; below is the code from the parent task
(require "Elementary_cellular_automata.rkt")
Line 306 ⟶ 1,128:
(show-automaton v #:step step #:push-right o)
(newline)
(ng/90/infinite v o)))</
{{out}}
Line 352 ⟶ 1,174:
#fx(536879104 0 33554944)
0</pre>
=={{header|Raku}}==
(formerly Perl 6)
This version, while it is ''capable'' of working with infinite length cellular automata, makes the assumption that any cells which have not been explicitly examined are in a 'null' state, neither '0' or '1'. Further it makes the assumption that a null cell, on being examined, initially contains nothing (░). Otherwise it would take infinite time to calculate every row and would be exceptionally boring to watch.
Based heavily on the code from the [[One-dimensional_cellular_automata#Raku|One-dimensional cellular automata]] task. Example uses rule 90 (Sierpinski triangle).
<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)
],
' '
)
}
}
my Automaton $a .= new: :rule(90), :cells(flat '010'.comb);
# display the first 20 rows
say $a++ for ^20;
# then calculate the other infinite number of rows, (may take a while)
$a++ for ^Inf;</syntaxhighlight>
{{out}}
<pre>░▲░
░▲░▲░
░▲░░░▲░
░▲░▲░▲░▲░
░▲░░░░░░░▲░
░▲░▲░░░░░▲░▲░
░▲░░░▲░░░▲░░░▲░
░▲░▲░▲░▲░▲░▲░▲░▲░
░▲░░░░░░░░░░░░░░░▲░
░▲░▲░░░░░░░░░░░░░▲░▲░
░▲░░░▲░░░░░░░░░░░▲░░░▲░
░▲░▲░▲░▲░░░░░░░░░▲░▲░▲░▲░
░▲░░░░░░░▲░░░░░░░▲░░░░░░░▲░
░▲░▲░░░░░▲░▲░░░░░▲░▲░░░░░▲░▲░
░▲░░░▲░░░▲░░░▲░░░▲░░░▲░░░▲░░░▲░
░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░▲░
░▲░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▲░
░▲░▲░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▲░▲░
░▲░░░▲░░░░░░░░░░░░░░░░░░░░░░░░░░░▲░░░▲░
░▲░▲░▲░▲░░░░░░░░░░░░░░░░░░░░░░░░░▲░▲░▲░▲░
^C
</pre>
=={{header|Ruby}}==
{{trans|Python}}
<
c.tr('01','10')
end
Line 379 ⟶ 1,258:
end
end
end</
The output is the same as the Python entry.
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">func evolve(rule, bin) {
var offset = 0
var (l='', r='')
Inf.times {
bin.sub!(/^((.)\g2*)/, {|_s1, s2| l = s2; offset -= s2.len; s2*2 })
bin.sub!(/(.)\g1*$/, {|s1| r = s1; s1*2 })
printf("%5d| %s%s\n", offset, ' ' * (40 + offset), bin.tr('01','.#'))
bin = [l*3, 0.to(bin.len-3).map{|i| bin.substr(i, 3) }..., r*3 ].map { |t|
1 & (rule >> t.bin)
}.join
}
}
evolve(90, "010")</syntaxhighlight>
{{out}}
<pre>
-1| ..#..
-2| ..#.#..
-3| ..#...#..
-4| ..#.#.#.#..
-5| ..#.......#..
-6| ..#.#.....#.#..
-7| ..#...#...#...#..
-8| ..#.#.#.#.#.#.#.#..
-9| ..#...............#..
-10| ..#.#.............#.#..
-11| ..#...#...........#...#..
-12| ..#.#.#.#.........#.#.#.#..
-13| ..#.......#.......#.......#..
-14| ..#.#.....#.#.....#.#.....#.#..
-15| ..#...#...#...#...#...#...#...#..
-16| ..#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#..
-17| ..#...............................#..
-18| ..#.#.............................#.#..
-19| ..#...#...........................#...#..
-20| ..#.#.#.#.........................#.#.#.#..
⋮
</pre>
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
<
oo::class create InfiniteElementaryAutomaton {
Line 439 ⟶ 1,359:
$rule run 25
$rule destroy
}</
{{out}}
<pre>
Line 496 ⟶ 1,416:
….##..#...###..####...##.#####...#.#####.#..#.....#.…
.##.####.##..###...#.##..#....#.##.#.....#####...###.
</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
var addNoCells = Fn.new { |s|
var l = (s[0] == "*") ? "." : "*"
var r = (s[-1] == "*") ? "." : "*"
for (i in 0..1) {
s.insert(0, l)
s.add(r)
}
}
var step = Fn.new { |cells, rule|
var newCells = []
for (i in 0...cells.count - 2) {
var bin = 0
var b = 2
for (n in i...i + 3) {
bin = bin + (((cells[n] == "*") ? 1 : 0) << b)
b = b >> 1
}
var a = ((rule & (1 << bin)) != 0) ? "*" : "."
newCells.add(a)
}
return newCells
}
var evolve = Fn.new { |l, rule|
System.print(" Rule #%(rule):")
var cells = ["*"]
for (x in 0...l) {
addNoCells.call(cells)
var width = 40 + (cells.count >> 1)
Fmt.print("$*s", width, cells.join())
cells = step.call(cells, rule)
}
}
evolve.call(35, 90)
System.print()</syntaxhighlight>
{{out}}
<pre>
Rule #90:
..*..
..*.*..
..*...*..
..*.*.*.*..
..*.......*..
..*.*.....*.*..
..*...*...*...*..
..*.*.*.*.*.*.*.*..
..*...............*..
..*.*.............*.*..
..*...*...........*...*..
..*.*.*.*.........*.*.*.*..
..*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................*..
..*.*.............................*.*..
..*...*...........................*...*..
..*.*.*.*.........................*.*.*.*..
..*.......*.......................*.......*..
..*.*.....*.*.....................*.*.....*.*..
..*...*...*...*...................*...*...*...*..
..*.*.*.*.*.*.*.*.................*.*.*.*.*.*.*.*..
..*...............*...............*...............*..
..*.*.............*.*.............*.*.............*.*..
..*...*...........*...*...........*...*...........*...*..
..*.*.*.*.........*.*.*.*.........*.*.*.*.........*.*.*.*..
..*.......*.......*.......*.......*.......*.......*.......*..
..*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*.....*.*..
..*...*...*...*...*...*...*...*...*...*...*...*...*...*...*...*..
..*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*.*..
..*...............................................................*..
..*.*.............................................................*.*..
..*...*...........................................................*...*..
</pre>
=={{header|zkl}}==
{{trans|D}}
<syntaxhighlight lang="zkl">nLines,flipCell := 25, fcn(c){ (c=="1") and "0" or "1" };
foreach rule in (T(90,30)){
println("\nRule: ", rule);
ruleBits:="%08.2B".fmt(rule); // eg 90-->"01011010"
neighs2next:=(8).pump(Dictionary(),
'wrap(n){ T("%03.2B".fmt(n), ruleBits.reverse()[n]) });
C:="1"; // C is "1"s and "0"s, I'll auto cast to Int as needed
foreach i in (nLines){
println("%2d: %s%s".fmt(i," "*(nLines - i), C.translate("01",".#")));
C=String(flipCell(C[0])*2, C, flipCell(C[-1])*2);
C=[1..C.len()-2].pump(String,'wrap(n){ neighs2next[C[n-1,3]] });
}
}</syntaxhighlight>
{{out}}
<pre>
Rule: 90
0: #
1: #.#
2: #...#
3: #.#.#.#
4: #.......#
5: #.#.....#.#
6: #...#...#...#
7: #.#.#.#.#.#.#.#
8: #...............#
9: #.#.............#.#
10: #...#...........#...#
11: #.#.#.#.........#.#.#.#
12: #.......#.......#.......#
13: #.#.....#.#.....#.#.....#.#
14: #...#...#...#...#...#...#...#
15: #.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#
16: #...............................#
17: #.#.............................#.#
18: #...#...........................#...#
19: #.#.#.#.........................#.#.#.#
20: #.......#.......................#.......#
21: #.#.....#.#.....................#.#.....#.#
22: #...#...#...#...................#...#...#...#
23: #.#.#.#.#.#.#.#.................#.#.#.#.#.#.#.#
24: #...............#...............#...............#
Rule: 30
0: #
1: ###
2: ##..#
3: ##.####
4: ##..#...#
5: ##.####.###
6: ##..#....#..#
7: ##.####..######
8: ##..#...###.....#
9: ##.####.##..#...###
10: ##..#....#.####.##..#
11: ##.####..##.#....#.####
12: ##..#...###..##..##.#...#
13: ##.####.##..###.###..##.###
14: ##..#....#.###...#..###..#..#
15: ##.####..##.#..#.#####..#######
16: ##..#...###..####.#....###......#
17: ##.####.##..###....##..##..#....###
18: ##..#....#.###..#..##.###.####..##..#
19: ##.####..##.#..######..#...#...###.####
20: ##..#...###..####.....####.###.##...#...#
21: ##.####.##..###...#...##....#...#.#.###.###
22: ##..#....#.###..#.###.##.#..###.##.#.#...#..#
23: ##.####..##.#..###.#...#..####...#..#.##.######
24: ##..#...###..####...##.#####...#.#####.#..#.....#
</pre>
|