Do you know where your variables are? PerlMonks

### 1-D Cellular Automata

by YuckFoo (Abbot)
 on Jun 19, 2002 at 19:28 UTC ( #175816=CUFP: print w/replies, xml ) Need Help??

Recent discussion of Pascal's triangle reminded me of a cool 1-D Cellular Automata and Wolfram's famous Rule 30.

Try \$rule = 18, 22, 30, 45, 54, 110, or 150 for some snazzy Pascal's Triangle variations.

RuleFoo

update: Also rules 122, 126, 129, 146, 151

```#!/usr/bin/perl

use strict;

my \$rule = shift || 30;
my \$wide = shift || 80;
my \$high = shift || 60;

my \$binary = reverse(substr(sprintf("%8.8b", \$rule), -8, 8));
\$binary =~ tr/01/ */;
#print "\$binary\n";

my (%rules, \$key, \$i);

for (\$i = 7; \$i >= 0; \$i--) {
\$key = sprintf("%3.3b", \$i);
\$key =~ tr/01/ */;
\$rules{\$key} = substr(\$binary, \$i, 1);
#print "\$key \$rules{\$key}\n";
}

my (\$str, @chs);

for (1..\$wide) {
if (rand(2) < 1) { \$str .= ' '; }
else             { \$str .= '*'; }
}

for (1..\$high) {
@chs = split('', \$str);
print "\$str\n";
\$str = '';
for (\$i = 0; \$i < \$wide; \$i++) {
\$key = "\$chs[\$i-1]\$chs[\$i]\$chs[(\$i+1)%@chs]";
\$str .= \$rules{\$key};
}
}

Replies are listed 'Best First'.
Re: 1-D Cellular Automata
by gumby (Scribe) on Jun 19, 2002 at 19:33 UTC
I was waiting for another one of these posts ;-) Rule 90 will generate Sierpinski's sieve (but then, you can in turn generate that from Pascal's triangle (mod 2)).

```  #!/usr/bin/perl -w

use strict;

my (\$file, %rules, \$string, \$rewrite, \$angle, \$i);

\$file = "gosper";

# Peano-Gosper curve.
\$rules{"X"} = "X+YF++YF-FX--FXFX-YF+";
\$rules{"Y"} = "-FX+YFYF++YF+FX--FX-Y";
\$string = "FX"; \$angle = 60; \$i = 4;

foreach (1..\$i) {
\$rewrite = "";
for (split //,\$string) {
\$rewrite .= \$rules{\$_} || \$_;
}
\$string = \$rewrite;
}

open PS,">\$file.ps";
print PS "%#\n\n";
print PS "306 396 moveto\n";
for my \$ch (split //,\$string) {
if (\$ch eq 'f') {
print PS "0 1 rlineto\n";
} elsif (\$ch eq 'F') {
print PS "0 1 rmoveto\n";
} elsif (\$ch eq '+') {
print PS "360 \$angle rotate\n";
} elsif (\$ch eq '-') {
print PS "360 \$angle neg rotate\n";
} elsif (\$ch eq '!') {
print PS "-1 1 scale\n";
} elsif (\$ch eq '[') {
print PS "gsave\n";
} elsif (\$ch eq ']') {
print PS "stroke\ngrestore\n";
}
}
print PS "stroke\nshowpage";
close PS;

Note that you need to replace uppercase F with lowercase f to turn on the 'pen'.

I like L-systems. A few years ago I wrote an L-system which displayed a Koch snowflake in postscript, for one of the early TPJ obfuscated perl contests, but I don't think it qualified due to the postscript. Maybe I'll post it in the obfuscation section if I can dig it up.

Unfortunately, since then, I haven't found any good turtle-graphics style module to support interesting L-system output. There was (is?) a Graphics::Turtle module (or something similar) in CPAN, but according to the author it was an idea, not an implementation.

However, using postscript for turtle graphics output is pretty easy, if you don't mind using a postscript viewer to look at the output. Instead of rotating your "turtle" and calculating a new (X, Y) based on your angle and a fixed radius, translate your current position to (0, 0), rotate the world around the origin, and then draw a line to (say) (0, 1). Using postscript as my output device, the snowflake generator was under 4 80-character lines long, including unnecessary obfuscation and without any external module dependancies.

I hope this provides some inspiration :) If I don't find my old postscript L-system generator maybe I'll rewrite it and post it here somewhere.

Alan

Thanks, great post. I've changed quite a bit of (cut out a lot of) code (and made some refinements) so I've posted a working version.
Re: 1-D Cellular Automata
by gumby (Scribe) on Jun 19, 2002 at 21:36 UTC
Sierpinski sieve:
```#!/usr/bin/perl -wl
\$_="co";
while (1) { s/..(?=c)/\$&^"CO"/eg; s/^/ /; print; }
Now, why does this work? Because binom(m, n)(mod 2) = n XOR m, so this is just Pascal's triangle (mod 2).

Update: Will work now.

why does this work?

It doesn't, at least, not with 5.6.1, or 5.005_03.

Does it need 5.8?

Edit: As petral points out, the regex will never match. I should have noticed that myself, instead of just trying the code...
--
Mike

\$_="co" will never match /..(?=c)/.

p
Re: 1-D Cellular Automata
by punkcraft (Pilgrim) on Jun 26, 2002 at 17:37 UTC
I was playing with this with large values for width and height and found that I could get a 5 fold decrease in runtime by replacing the last for loop with this:

```for (1..\$high) {
print "\$str\n";

\$prev_str = substr(\$str, -1, 1) . \$str .  substr(\$str, 0, 1);

\$str = '';

for (\$i = 0; \$i < \$wide; \$i++) {
\$str .= \$rules{substr(\$prev_str, \$i, 3 )};
}
}

Create A New User
Node Status?
node history
Node Type: CUFP [id://175816]
Approved by ignatz
Front-paged by jarich
help
Chatterbox?
 [ambrus]: Corion: yes, I've found Prima on cpan, but can you point to where its event loop is documented? [Corion]: ambrus: I think the event loop is not really documented but implicit in X11 or Windows... [ambrus]: One more obvious possible workaround is to just have the GUI of your program freeze for as long as the HTTP is running; [Corion]: brb [ambrus]: or, if Prima supports this, embedding its event loop to an outer main event loop, and running AnyEvent::HTTP in that outer one. [ambrus]: Corion: I think there's already some form of AnyEvent integration for Prima, according to https://metacpan. org/source/ KARASIK/Prima-1. 49/examples/ socket_anyevent.pl [ambrus]: a FAQ question [ambrus]: ah, apparently that's the POE thing you were talking about [ambrus]: Ok, but if there's a POE integration, then I again suggest that you consider using IO::Async::Loop:: Poe . I don't know if that will work.

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (14)
As of 2016-12-07 16:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
On a regular basis, I'm most likely to spy upon:

Results (130 votes). Check out past polls.