Code: Select all
#!/usr/bin/perl
# Create Wn.trees for odd numbered Wolfram 1D Rules 1-255
# by Tony Smith, Meme Media, Melbourne, Australia, January 2011
# extends Golly/Rules/TreeGenerators/RuleTreeGen.pl
# using Mark Jeronimus's approach of a next line of state 2 cells
use strict;
my ( @bits, %world, $nodeseq, @r, @params );
my $numStates = 3 ;
my $numNeighbors = 8 ;
my $numParams = $numNeighbors + 1 ;
for ( my $odd = 1; $odd < 256; $odd += 2 ) {
my $rule = $odd;
foreach my $bit ( 0 .. 7 ) { $bits[$bit] = $rule & 1; $rule = $rule >> 1 }
%world = ();
$nodeseq = 0;
@r = ();
@params = (0) x $numParams;
recur($numParams);
open ( NEW, '>', "W$odd.tree" ) || die "Cannot open file for output!";
print NEW "num_states=$numStates\n";
print NEW "num_neighbors=$numNeighbors\n";
print NEW "num_nodes=", scalar @r, "\n";
print NEW "$_\n" for @r ;
close NEW;
}
sub f {
my ($nw, $ne, $sw, $se, $n, $w, $e, $s, $c) = @_ ;
if ( $nw == 2 or $n == 2 or $ne == 2 ) { return 2 } # allow widening patterns
elsif ( $c != 2 ) { return $c } # past rows
else { return $bits[ 4 * $nw + 2 * $n + $ne ] } # next row
}
sub recur {
my $at = shift;
return f(@params) if $at == 0;
my $n = $at;
for (my $i=0; $i<$numStates; $i++) {
$params[$numParams-$at] = $i;
$n .= " " . recur($at-1);
}
return $world{$n} if defined($world{$n});
$world{$n} = $nodeseq;
push @r, $n;
return $nodeseq++;
}
Code: Select all
# Validates 1D rule/seed combination and adds next line indicator cells.
# Author: Tony Smith (ts@meme.com.au), January 2010.
use strict;
g_exit( 'There is no pattern.' ) if g_empty();
my $rulestring = g_getrule();
my ( $rule, $bounds ) = split( ':', $rulestring );
g_exit( 'Only for odd W rules.' ) unless $rule =~ s/W// and $rule > 0 and $rule < 256 and $rule % 2 == 1;
my @seedrect = g_getrect();
g_exit( 'Seed pattern must be only one cell high.' ) unless $seedrect[3] == 1;
my $cells = g_getcells( @seedrect );
if ( scalar @$cells % 2 ) { # may contain some state 2 cells
my @replace;
while ( scalar @$cells ) {
my @cell = splice( @$cells, 0, 3 );
$cell[2] = 1 if $cell[2] == 2; # convert any state 2 to state 1 in case seeded by randfill
push( @replace, @cell );
}
g_putcells( \@replace );
}
my $width = g_getwidth();
my ( $left, $right );
if ( $width ) { # bounded
$left = - int ( $width / 2 );
$right = $width + $left;
}
else { # unbounded
$left = $seedrect[0] - 1;
$right = $seedrect[0] + $seedrect[2];
}
for ( my $x = $left; $x < $right; $x ++ ) { g_setcell( $x, $seedrect[1] + 1, 2 ) }