#!/usr/bin/perl -w # Copyright 2012 Kevin Ryde # This file is part of Math-PlanePath. # # Math-PlanePath is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 3, or (at your option) any later # version. # # Math-PlanePath is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # for more details. # # You should have received a copy of the GNU General Public License along # with Math-PlanePath. If not, see . # Usage: perl cellular-rules.pl # # Print the patterns from the CellularRule paths with "*"s. # Rules with the same output are listed together. # # Implementation: # # Points are plotted by looping $n until its $y coordinate is beyond the # desired maximum rows. @rows is an array of strings of length 2*size+1 # spaces each in which "*"s are applied to plot points. # # Another way to plot would be to loop over $x,$y for the desired rectangle # and look at $n=$path->xy_to_n($x,$y) to see which cells have defined($n). # Characters could be appended or join(map{}) to make an output $str in that # case. Going by $n should be fastest for sparse patterns, though # CellularRule is not blindingly quick either way. # # See Cellular::Automata::Wolfram for the same but with more options and a # graphics file output. # use 5.004; use strict; use Math::PlanePath::CellularRule; my $numrows = 15; # size of each printout my %seen; my $count = 0; my $mirror_count = 0; my $finite_count = 0; my @strs; my @rules_list; my @mirror_of; foreach my $rule (0 .. 255) { my $path = Math::PlanePath::CellularRule->new (rule => $rule); my @rows = (' ' x (2*$numrows+1)) x ($numrows+1); # strings of spaces for (my $n = $path->n_start; ; $n++) { my ($x,$y) = $path->n_to_xy($n) or last; # some patterns are only finitely many N values last if $y > $numrows; # stop at $numrows+1 many rows substr($rows[$y], $x+$numrows, 1) = '*'; } @rows = reverse @rows; # print rows going up the page my $str = join("\n",@rows); # string of all rows my $seen_rule = $seen{$str}; # possible previous rule giving this $str if (defined $seen_rule) { # $str is a repeat of an output already seen, note this $rule with that $rules_list[$seen_rule] .= ",$rule"; next; } my $mirror_str = join("\n", map {scalar(reverse)} @rows); my $mirror_rule = $seen{$mirror_str}; if (defined $mirror_rule) { $mirror_of[$mirror_rule] = " (mirror image is rule $rule)"; $mirror_of[$rule] = " (mirror image of rule $mirror_rule)"; $mirror_count++; } $strs[$rule] = $str; $rules_list[$rule] = $rule; $seen{$str} = $rule; $count++; if ($rows[0] =~ /^ *$/) { $finite_count++; } } foreach my $rule (0 .. 255) { my $str = $strs[$rule] || next; print "rule=$rules_list[$rule]", $mirror_of[$rule]||'', "\n"; print "\n$strs[$rule]\n\n"; } my $unmirrored_count = $count - $mirror_count; print "Total $count different rule patterns\n"; print "$mirror_count are mirror images of another\n"; print "$finite_count stop after a few cells\n"; exit 0;