Ruby, 206 200200 199
R=0q,i,*R=*-2..27
q=0
i=-1
puts"#{i+=1}: #{$.,s=(0-2..q).map{x=R.map{|j|!s||rand<0.05?[*?A..?Z,' '].sample: s[j]};[R.count{|i|x[i]=='METHINKS IT IS LIKE A WEASEL'[i]},x]}.max;q=99;smax;q=97;s.join} -- score: #$."until$.>27
The first line is simply a fancy way to define q=-2
, i=-1
, and R=(0..27).to_a
. All the work is done in the 4th2nd line:
puts"..."until$.>27 # Prints the string in quotes until we reach the desired score
^
|
+---+
|
"#{i+=1}: #{...} -- score: #$."
^ ^ ^
+--------|---------------|-- Generation counter
+----------+---------------|-- Current string
| +-- Score of current string (interpolates the `$.` variable)
|
#{$.,s=(0-2..q).map{...}.max;q=99;smax;q=97;s.join} # Generate the score & string
^ ^ ^ ^ ^ ^ ^
+---------|--|---|----|---|----|------- Store the score; this variable makes
| | | | | | string interpolation shorter.
+--|---|----|---+----|------- `q` automatically takes care of generating
| | | | the string vs randomizing the string.
+---|----|--------|------ Make 100 (or 1 the first time) strings,
| | | and compute their score.
| +--------|------- Take the string with the max score.
+------------------+ +------- `s` is stored as an array
|
x=R.map{...};[R.count{...},x] # Compute string and its score, store in array
^ ^ ^^ ^
+-----|----|+-------|------ `R` is 0..27, we use the constant to save chars.
| +--------|------ `max` orders by first element, then second. We clearly want
| | the highest score, so make the score first.
+-------+-------------|------ Generate the string, store in `x`.
| +------ Count the number of chars that overlap with 'METHINKS...'
| |
| {|i|x[i]=='METHINKS IT IS LIKE A WEASEL'[i]}
{|j|!s||rand<0.05?[*?A..?Z,' '].sample: s[j]}
^ ^ ^ ^ ^
+---+---------|-------------|-------|---- 5% chance of randomizing, or 100% for
| | | first string.
+-------------+-------|---- Sample from alphabet + ' '.
+---- Don't alter the string 95% of the time