use v6-alpha; ## # Script to output Wolfram-esque cellular automata # # usage: 'perl ca_wolfram.pl', followed by: # -r rule_number (Specify in decimal, integer from 0 to 255) # -s steps (Specify number of steps to display) # -w width # -i initial_state # -t true_char # -f false_char ## use Getopt::Std; my %opts = getopts( 'rswitf' ); ## # options, with some reasonable defaults my $rule_number = %opts || 110; my $steps = %opts || 30; my $width = %opts || 30; my $initial = %opts || 'right'; my $true_char = %opts || 'x'; my $false_char = %opts || '.'; ## # Single cell in the left, right, or middle for initial state my $left = $steps; my $right = $width + $steps - 1; $width += ( $steps * 2 ); my $middle = int( $width / 2 ); ## # Initialize and fill up the array with 0 my Bool @line = 0 xx ($width-1); ## # Set an initial state on the left, right, or middle given $initial { when 'left' { @line[$left] = 1 } when 'right' { @line[$right] = 1 } when 'middle' { @line[$middle] = 1 } } ## # Unpack the Wolfram rule number into a hash my Bool %rule_hash; for ( 0 .. 7 ) -> $key { %rule_hash{$key} = ?($rule_number +& (1 ~ 0 x $key) ); } ## # Print the rule hash, using shiny, new sprintf say "Rule $rule_number:"; for %rule_hash.keys -> $key { say sprintf("%03b",$key) ~ " becomes " ~ +%rule_hash{$key}; } ## # Render the output on the screen. my $beginprint = $steps; my $endprint = @line.elems() - $steps; while ( $steps-- ) { my $newline = (+<<@line[ $beginprint .. $endprint ]).join("") ; $newline ~~ s:g/1/$true_char/; $newline ~~ s:g/0/$false_char/; say $newline; my @old_line = @line; for ( 0 .. $width - 3 ) -> $index { my $index_key = :2((+<<@old_line[ $index .. $index + 2 ]).join("")); @line[ $index + 1 ] = %rule_hash{$index_key}; } }