46 lines
927 B
Perl
46 lines
927 B
Perl
use List::Util 'reduce';
|
|
use List::MoreUtils 'false';
|
|
|
|
### Generally useful declarations
|
|
|
|
sub randElm
|
|
{$_[int rand @_]}
|
|
|
|
sub minBy (&@)
|
|
{my $f = shift;
|
|
reduce {$f->($b) < $f->($a) ? $b : $a} @_;}
|
|
|
|
sub zip
|
|
{@_ or return ();
|
|
for (my ($n, @a) = 0 ;; ++$n)
|
|
{my @row;
|
|
foreach (@_)
|
|
{$n < @$_ or return @a;
|
|
push @row, $_->[$n];}
|
|
push @a, \@row;}}
|
|
|
|
### Task-specific declarations
|
|
|
|
my $C = 100;
|
|
my $mutation_rate = .05;
|
|
my @target = split '', 'METHINKS IT IS LIKE A WEASEL';
|
|
my @valid_chars = (' ', 'A' .. 'Z');
|
|
|
|
sub fitness
|
|
{false {$_->[0] eq $_->[1]} zip shift, \@target;}
|
|
|
|
sub mutate
|
|
{my $rate = shift;
|
|
return [map {rand() < $rate ? randElm @valid_chars : $_} @{shift()}];}
|
|
|
|
### Main loop
|
|
|
|
my $parent = [map {randElm @valid_chars} @target];
|
|
|
|
while (fitness $parent)
|
|
{$parent =
|
|
minBy \&fitness,
|
|
map {mutate $mutation_rate, $parent}
|
|
1 .. $C;
|
|
print @$parent, "\n";}
|