Golfing A Weasel Program
APL (143)
0{⍵≢T←'METHINKS IT IS LIKE A WEASEL':c∇⍨1+⍺⊣⎕←(⍕⍺),':'c'-- score:',s⊣c←⊃c/⍨G=s←⌈/G←{+/⍵=T}¨c←{⍵{⍵:⍺⋄C[?27]}¨9≠?28/20}¨100⍴⊂⍵}⊃∘(C←27↑⎕A)¨?28/27
Explanation:
0{
...}⊃∘(C←27↑⎕A)¨?28/27
: setC
to the first 27 capital letters. There are only 26, so the 27th element will be a space. Select 28 random items fromC
. This will be the first⍵
. The first⍺
(generation) will be0
.⍵≢T←'METHINKS IT IS LIKE A WEASEL
: setT
to the string'METHINKS IT IS LIKE A WEASEL'
. As long as⍵
is not equal toT
:{
...}¨100⍴⊂⍵
: Make 100 copies of⍵
. For each of these...9≠?28/20
: select 28 random numbers from 1 to 20. Make a bitmask where each1
means that the random number was not equal to9
. (This means 5% chance of a0
).⍵{⍵:⍺⋄C[?27]}¨
: for each letter in⍵
, if the corresponding bit was1
, keep that letter, otherwise replace it with a randomly chosen element fromC
.
c←
: store the 100 mutated strings inc
.G←{+/⍵=T}¨c
: for each element inc
, calculate the score (amount of characters that matchT
) and store the scores inG
.s←⌈/G
: find the maximum score and store that ins
.c←⊃c/⍨G=s
: select the first item fromc
whose score is equal tos
(the maximum), and store it inc
again.⎕←(⍕⍺),':'c'-- score:',s
: print the generation in the given format (⍺
is current generation,c
is current best string,s
is score)c∇⍨1+⍺
: Increment the generation and run the mutation again using the current best string (c
) as input.
Mathematica - 238 236 225
c:="@"~CharacterRange~"Z"~RandomChoice~28/."@"->" "
For[s=""<>c;i=0,{d,s}=Sort[{#~HammingDistance~"METHINKS IT IS LIKE A WEASEL",#}&@
StringReplace[s,_/;20Random[]<1:>c〚1〛]&~Array~100]〚1〛;
d>0Print[i++,":"s," -- score: ",28-d],]
Example output
0: CYPMEIHADXRXVTFHERYOZNRVFCSQ -- score: 0
1: CYPMEIHADIRXVTFBERYOZNRVFCSQ -- score: 1
2: CYPMEIHA IRXVTFBIRYOZNRVFCSQ -- score: 3
...
50: METHINKS IT IS LIKE A WEASEL -- score: 28
Python (273)
from random import choice as c
n=range
a=map(chr,n(65,91)+[32])
s=map(c,[a]*28)
p=x=0
while p<28:
p,s=max((sum(g==r for g,r in zip(y,'METHINKS IT IS LIKE A WEASEL')),y)for y in ([c(a+[x]*513)for x in s]for _ in n(100)));print '%d: %s -- score: %d' % (x,''.join(s),p);x+=1