Elementary cellular automaton/Infinite length: Difference between revisions
(Undo revision 178923 by Ledrug. Correct for this definition of 'infinite'. See talk page.) |
(+ D entry) |
||
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|D}}==
{{trans|Python}}
<lang d>import std.stdio, std.array, std.range, std.typecons, std.string, std.conv;
alias R = replicate;
void main() {
enum nLines = 25;
enum notCell = (in char c) pure => (c == '1') ? "0" : "1";
foreach (immutable rule; [90, 30]) {
writeln("\nRule: ", rule);
immutable ruleBits = "%08b".format(rule).retro.text;
const neighs2next = 8.iota
.map!(n => tuple("%03b".format(n), [ruleBits[n]]))
.assocArray;
string C = "1";
foreach (immutable i; 0 .. nLines) {
writefln("%2d: %s%s", i, " ".R(nLines - i), C.tr("01", ".#"));
C = notCell(C[0]).R(2) ~ C ~ notCell(C[$ - 1]).R(2);
C = iota(1, C.length - 1)
.map!(i => neighs2next[C[i - 1 .. i + 2]])
.join;
}
}
}</lang>
=={{header|Perl}}==
|
Revision as of 19:53, 29 May 2014
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.
To be precise, consider the state of the automaton to be made of an infinite number of cells, but with a bounded support. In other words, to describe the state of the automaton, you need a finite number of adjacent cells, along with their individual state, and you then consider that the individual state of each of all other cells is the negation of the closest individual cell among the previously defined finite number of cells.
Examples:
1 -> ..., 0, 0, 1, 0, 0, ... 0, 1 -> ..., 1, 1, 0, 1, 0, 0, ... 1, 0, 1 -> ..., 0, 0, 1, 0, 1, 0, 0, ...
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.
D
<lang d>import std.stdio, std.array, std.range, std.typecons, std.string, std.conv; alias R = replicate;
void main() {
enum nLines = 25; enum notCell = (in char c) pure => (c == '1') ? "0" : "1";
foreach (immutable rule; [90, 30]) { writeln("\nRule: ", rule); immutable ruleBits = "%08b".format(rule).retro.text; const neighs2next = 8.iota .map!(n => tuple("%03b".format(n), [ruleBits[n]])) .assocArray;
string C = "1"; foreach (immutable i; 0 .. nLines) { writefln("%2d: %s%s", i, " ".R(nLines - i), C.tr("01", ".#")); C = notCell(C[0]).R(2) ~ C ~ notCell(C[$ - 1]).R(2); C = iota(1, C.length - 1) .map!(i => neighs2next[C[i - 1 .. i + 2]]) .join; } }
}</lang>
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. <lang perl>sub evolve { my ($rule, $_) = @_; my $offset = 0;
while (1) { my ($l, $r, $st); s/^((.)\g2*)/$2$2/ and $l = $2, $offset -= length($2); s/(.)\g1*$/$1$1/ and $r = $1;
$st = $_;
tr/01/.#/; printf "%5d| %s%s\n", $offset, ' ' x (40 + $offset), $_;
$_ = join , map(1 & ($rule>>oct "0b$_"), $l x 3, map(substr($st, $_, 3), 0 .. length($st)-3), $r x 3); } }
evolve(90, "010");</lang>
- Output:
-1| ..#.. -2| ..#.#.. -3| ..#...#.. -4| ..#.#.#.#.. -5| ..#.......#.. -6| ..#.#.....#.#.. -7| ..#...#...#...#.. -8| ..#.#.#.#.#.#.#.#.. -9| ..#...............#.. -10| ..#.#.............#.#.. -11| ..#...#...........#...#.. -12| ..#.#.#.#.........#.#.#.#.. -13| ..#.......#.......#.......#.. ---(infinite more lines snipped)---
Python
Infinite generator but only print 25 lines of each rule.
<lang python>def _notcell(c):
return '0' if c == '1' else '1'
def eca_infinite(cells, rule):
lencells = len(cells) rulebits = '{0:08b}'.format(rule) neighbours2next = {'{0:03b}'.format(n):rulebits[::-1][n] for n in range(8)} c = cells while True: yield c c = _notcell(c[0])*2 + c + _notcell(c[-1])*2 # Extend and pad the ends
c = .join(neighbours2next[c[i-1:i+2]] for i in range(1,len(c) - 1)) #yield c[1:-1]
if __name__ == '__main__':
lines = 25 for rule in (90, 30): 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', '#')))</lang>
- Output:
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: ##..#...###..####...##.#####...#.#####.#..#.....#