#!/usr/bin/env perl use strict; use warnings; use POSIX; use utf8; binmode(STDOUT, ":utf8"); # Get arguments my $gens = $ARGV[0]; my $width = $ARGV[1]; my $rule = $ARGV[2]; # Set num_rules to 255 and bits to 8 by default my $num_rules = $ARGV[3]; my $bits = 8; if($num_rules) { $bits = floor(log($num_rules)/log(2)) + 1; } else { $num_rules = 255; } # Set up all possible rules 0 - 255 # 0 = 00000000 # 1 = 00000001 # ... # 254 = 11111110 # 255 = 11111111 my @rules; for (my $index = $num_rules; $index >=0; $index--) { push @rules, [get_bin($index, $bits)]; } # extract the correct binary number for this position and this rule sub get_val_at_pos { my ($binstr) = @_; my $pos = sprintf ('%d', $binstr); return $rules[$rule][$pos]; } # Get the binary representation of a number as an array of 1's and 0's sub get_bin{ my ($dec, $padding) = @_; my $bin = sprintf('%0' . $padding .'b',$dec); my @binarr = split(//,$bin); return @binarr; } # Set up the initial condition to be all 1's except fo one 0 in the middle sub set_up_init { my @init; my $half = $width / 2; unless ($width % 2 == 0) { $half = $half + 0.5; } for (my $i = 0; $i < $width; $i++) { if($i == $half - 1) { $init[$i] = 0; } else { $init[$i] = 1; } } return @init; } sub print_arr { foreach my $elem (values @_) { if($elem) { print " "; } else { print "■"; } } print "\n"; #sleep 0.5; } # Print usage sub usage { print "$0 [num rules]\n"; } # Some error handling if (scalar @ARGV < 3 or $rule > $num_rules) { usage; exit 1; } # Get the initial condition and print it out my @initial = set_up_init; print_arr @initial; #print "\n"; # Now loop through all the generations for (my $gen = 0; $gen < $gens; $gen++) { # This is the next evoultion of the the automation my @next; for (my $elem = 0; $elem < $width ; $elem++) { # Boundary conditions handled by modulo so we wrap around my $state = $initial[ ($elem - 1) % $width] . $initial[$elem] . $initial[ ($elem +1) % $width]; # Get the corresponding value for this state $next[$elem] = get_val_at_pos oct("0b".$state); } # The next state is now the new initial @initial = @next; # Print it out print_arr @initial; #print "\n"; } exit 0