Created
July 27, 2017 07:10
-
-
Save jaldhar/bae299ee03df93fcdd3633d751581e0b to your computer and use it in GitHub Desktop.
Trying to implement an iterator in Perl6
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=begin pod | |
Algorithm::DawkinsWeasel is a simple model illustrating the idea of cumulative | |
selection in evolution. | |
The original form of it looked like this: | |
1. Start with a random string of 28 characters. | |
2. Make 100 copies of this string, with a 5% chance per character of that | |
character being replaced with a random character. | |
3. Compare each new string with "METHINKS IT IS LIKE A WEASEL", and give | |
each a score (the number of letters in the string that are correct and | |
in the correct position). | |
4. If any of the new strings has a perfect score (== 28), halt. | |
5. Otherwise, take the highest scoring string, and go to step 2 | |
This module parametrizes the target string, mutation threshold, and number of | |
copies per round. | |
The goal is to be able to use it something like this: | |
my $weasel = Algorithm::DawkinsWeasel.new; | |
say $weasel.current-phrase while $weasel; | |
=end pod | |
unit class Algorithm::DawkinsWeasel:ver<0.0.2> does Iterator; | |
has Str @.target-phrase; | |
has Rat $.mutation-threshold; | |
has Int $.copies; | |
has Str @!charset; | |
has Int $!count; | |
has Str @!current-phrase; | |
has Int $!hi-score; | |
submethod BUILD(Str :$target-phrase = 'METHINKS IT IS LIKE A WEASEL', | |
Rat :$mutation-threshold = 0.05, Int :$copies = 100) { | |
@!target-phrase = $target-phrase.comb; | |
$!mutation-threshold = $mutation-threshold; | |
$!copies = $copies; | |
} | |
submethod TWEAK { | |
@!charset = | ['A' .. 'Z'] , ' '; | |
@!current-phrase = map { @!charset.pick }, 0 .. @!target-phrase.end; | |
$!hi-score = 0; | |
$!count = 0; | |
} | |
method evolve { | |
for (1 .. $!copies) { | |
my @trial = map { | |
1.rand < $!mutation-threshold ?? @!charset.pick !! $_; | |
}, @!current-phrase; | |
my Int $score = 0; | |
for 0 .. @!target-phrase.end -> $i { | |
if @trial[$i] eq @!target-phrase[$i] { | |
$score++; | |
} | |
} | |
if $score > $!hi-score { | |
$!hi-score = $score; | |
@!current-phrase = @trial; | |
} | |
} | |
} | |
method pull-one { | |
$!count++; | |
self.evolve; | |
return $!hi-score == @!target-phrase.elems ?? IterationEnd !! self; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment