| Bytes | Lang | Time | Link |
|---|---|---|---|
| 360 | AWK | 250305T215138Z | xrs |
| 259 | PowerShell Core | 240912T102603Z | Julian |
| 201 | Zsh +coreutils | 240831T064219Z | roblogic |
| 272 | Python 2 | 140103T203204Z | tecywiz1 |
| 131 | Uiua | 240830T214611Z | noodle p |
| 207 | J | 240830T171122Z | Conor O& |
| 089 | Japt R | 180601T092243Z | Shaggy |
| 453 | Go | 240830T152328Z | bigyihsu |
| 098 | Japt | 191127T013507Z | Gymhgy |
| 219 | Perl 5 | 140106T221505Z | Dom Hast |
| 116 | Pyth | 180608T145811Z | Sok |
| 328 | JavaScript Node.js | 180601T115541Z | Muhammad |
| 108 | Japt v2.0a0 | 180531T062956Z | Bubbler |
| 199 | Ruby | 150825T010450Z | Justin |
| 198 | Ruby 225 202 203 | 140107T235243Z | Paul Pre |
| 281 | Julia | 150816T200250Z | kevinsa5 |
| 668 | C++ | 150707T115509Z | TobiasR. |
| 319 | Python 2.7 | 150705T094017Z | Beta Dec |
| 422 | Racket | 140112T030328Z | Sylweste |
| 376 | Javascript | 140111T220934Z | logic8 |
| 218 | Ruby | 140112T013901Z | Darren S |
| 420 | Haskell | 140111T135244Z | Toeofdoo |
| nan | Scala | 140103T191530Z | Rob Star |
| 314 | Groovy | 140109T171515Z | FGreg |
| 331 | C | 140110T195526Z | Sammo |
| nan | 140110T093801Z | brother | |
| 291 | R | 140110T140157Z | plannapu |
| 331 | C | 140108T221325Z | Christia |
| 321 | Python | 140103T223108Z | PsHegger |
| 167 | Golfscript 168 | 140109T222230Z | Joachim |
| 415 | PHP 429 426 421 | 140107T184852Z | Einacio |
| 282 | Python | 140103T115523Z | Noelkd |
| 256 | C | 140108T170747Z | Art |
| 534 | Java | 140109T142630Z | Radiodef |
| 238 | R | 140103T172459Z | Henrik |
| 246 | JavaScript | 140106T220636Z | apsiller |
| 312 | JavaScript | 140108T085652Z | rory |
| 632 | Java | 140108T121313Z | javatarz |
| 374 | SAS | 140108T055753Z | Joe |
| 207 | GolfScript | 140108T032207Z | Ben Reic |
| 284 | Python | 140107T192629Z | Sudharsa |
| 436 | C# | 140107T175336Z | tia |
| 167 | K | 140107T140324Z | tmartin |
| 143 | APL | 140103T132220Z | marinus |
| 225 | Mathematica | 140106T235552Z | ybeltuko |
| 410 | Ruby | 140106T234706Z | user1148 |
| 502 | Lua 5.1 | 140105T201056Z | finnbar |
| 442 | PHP | 140103T190034Z | Sammitch |
AWK, 360 bytes
func r(y){G=int(rand()*26);return sprintf("%c",G?G+64:32)}END{for(srand();i++<b=28;)u=u r()
for(;j++<a=100;)s=s u
for(;n<b;print l++": "o" -- score: "n){for(U=1;U<a*b;U+=28){for(k=X=m=J=0;J++<b;)T=T (int(rand()*20)?substr(substr(s,U,28),J,1):r())
for(;X++<b;)m+=substr(T,X,1)~substr("METHINKS IT IS LIKE A WEASEL",X,1)
if(m>n){n=m;o=T}for(T=s=_;k++<a;)s=s o}}}
PowerShell Core, 259 bytes
$ofs=''
sal e Get-Random
filter c{0..$_|%{'A'..'Z'+' '|e}}filter s{$i=$_
(0..27|?{$i[$_]-ne"METHINKS IT IS LIKE A WEASEL"[$_]}).Count}$s=27|c
do{"$(($i++)): $s -- score: $(28-($l=("$s"|s)))"
$s=(0..99|%{,($s|%{,$_*19+(c)|e})}|Sort-Object{"$_"|s})[0]}while($l)
Zsh +coreutils, 260 235 215 209 201 bytes
p()jot -cr $1 @ Z;T=METHINKS@IT@IS@LIKE@A@WEASEL;S=(`p 28`)
for i ({0..99}){V= j=;printf $i:\ ${(j::)S//@/ }
for x ($S)((#x!=##$T[++j]&&RANDOM%20))&&S[j]=`p 1`||((V++))
<<<" -- score: $V";((V==28))&&?}
Try it online!
209b
215b
235b
260b
Found the question a bit confusing, but eventually figured it out. For a minute I thought I had disproved* evolution!! (*actually a limitation of the zsh $RANDOM function in subshells)
Notes:
* Using @ in the target string allows me to use ASCII range 64-90
* Using jot -c -r 28 64 90 is better than repeatedly doing ${(#)$((RANDOM%27+64))}
* -20 bytes: removed "", squished jot parameters to -cr 1 @ Z, replaced exit with ? (crashes)
* -6 bytes: changed $S from string to array
* -8 bytes: replaced $n with expression ##$T[++j]; put jot calls into function p()
Python 2, 272 bytes
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
Uiua, 142 136 131 bytes
R←⊏:⊂@ +@A⇡26⌊×27≡⋅⚂
◌◌⍢(≡⍜▽R<0.05∵⊸⚂↯100|&p$"_: _ -- score: _":⊃⊙:⊓(≠28:|+1)⊃(⊡⊢⍖)/↥/+="METHINKS IT IS LIKE A WEASEL"⊸⍉)↯100R⊚28 0
Try it: Uiua pad
With spaces: pad
R ← ⊏:⊂@ +@A⇡26⌊×27≡⋅⚂
0
↯100R⊚28
◌◌⍢(
≡⍜▽R<0.05∵⊸⚂↯100
| /+="METHINKS IT IS LIKE A WEASEL"⊸⍉
⊃(⊡⊢⍖)/↥
&p$"_: _ -- score: _":⊃⊙:⊓(≠28:|+1))
I will write an explanation of the program soon.
I also found this alternate solution which is 135 bytes: pad, with spaces
◌◌⍢(≡⍜▽≡⋅⚂<0.05∵⊸⚂↯100|&p$"_: _ -- score _"⊃⊃⋅⋅⋅∘:⊓(≠28|⋅∘|+1)⊃/↥(∩⊡⟜:⊢⍖)/+="METHINKS IT IS LIKE A WEASEL"⊸⍉⊏⌊×27,⊂@ +@A⇡26)↯100[⍥⚂28]0
J, 222 207 bytes
0(Q=:(>:@[;([:(0{]\:G=:1#.T="1])100((i.+]*1=r@20)@28{],r@27)"{@>@$<)@][":@G echo@,~' -- score: ',~":@[,': ',A{~])&>/)@(Q^:(1-(T=:(A=:u:32,65+i.26)i.'METHINKS IT IS LIKE A WEASEL')-:1>@{])^:_)@;(r=:28?@$])@27
Reusable function which takes no input. By default, the RNG is seeded to 7^5 (16807) in a fresh instance, so re-running the TIO link does not change the output. To demonstrate it is random, I run it twice in the link.
As I've began doing in other answers, I've included some minor golfed variations to give insights into my golfing process:
Q =: [:(0{]\:G=:1#.T="1])[:((i.@28+28*1=r@20){],r@27)"{100&$&.<
Q =: [:(0{]\:G=:1#.T="1])[:((i.@28+28*1=r@20){],r@27)"{100>@$<
Q =: [:(0{]\:G=:1#.T="1])100((i.@28+28*1=r@20){],r@27)"{@>@$<
Q =: [:(0{]\:G=:1#.T="1])100((i.+]*1=r@20)@28{],r@27)"{@>@$<
(Somewhat) ungolfed
A=:u:32,65+i.26
T=:A i.'METHINKS IT IS LIKE A WEASEL'
r=:28?@$]
grade=:1 #. T ="1 ]
mut =: (i.@28+28*1=r@20){],r@27
gen =: [: mut"{ 100&$&.<
best =: 0 { ] \: grade
Q =: best@gen
Qcat =: ] [ [: echo (":@grade) ,~ ' -- score: ',~":@[,': ',A{~]
Qit =: (>:@[ ; Q@Qcat)&>/
Qcontinue =: 1&([-T-:>@{)
f =: 0 Qit@(Qit^:Qcontinue^:_)@;r@27
f ''
Old solution, 222 bytes
0 I@((I=:(>:@[;([:(0{]\:G"1)((28|i.100 28)+28*1=r@20){"1],"1 r@27)@(][[:echo":@(G=:1#.T=]),~' -- score: ',~":@[,': ',A{~]))&>/)^:(1&([-(T=:(A=:u:32,65+i.26)i.'METHINKS IT IS LIKE A WEASEL')-:>@{))^:_)@;0{(r=:100 28?@$])@27
I think there are still bytes to be saved: Right now, the program makes all the random mutations at once, and I think writing the mutation logic to be on a single sentence, and running that individually might be shorter. But I must work on this later. Sure enough, it was shorter!
(Somewhat) Ungolfed
A=:u:32,65+i.26
T=:A i.'METHINKS IT IS LIKE A WEASEL'
r=:100 28?@$]
grade =: 1 #. T = ]
Qgen =: ((28|i.100 28)+28*1=r@20){"1],"1 r@27
Qsel =: (0{]\:grade"1)
Q =: [: Qsel Qgen
Qcat =: ] [ [: echo (":@grade) ,~ ' -- score: ',~":@[,': ',A{~]
Qit =: (>:@[ ; Q@Qcat)&>/
Qcontinue =: 1&([-T-:>@{)
f =: 0 Qit@(Qit^:Qcontinue^:_)@;0{r@27
f ''
Japt -R, 94 91 90 89 bytes
Been trying to break 94 for years, and I finally did it :D
A different approach to, but (still) with a little inspiration from, Bubbler's solution.
;B±S ¬ö28
@=#dÆ£BùX540 öÃÃñèV o)ʶG}a@NpX+`: {¬} -- sÖ: {G=UèV=ÈoYg`Ú0ks ¦ke a Øâel
Test it (Warning: can be slow as hell!)
Explanation
;B±S ¬ö28
;B :Uppercase alphabet
± :Append and reassign result to variable B
S : Space
¬ :Split
ö28 :Generate an array of 28 random characters
:Assign that array to variable U
@=#dÆ£BùX540 öÃÃñèV o)ʶG}a@NpX+`: {¬}...{G=UèV=ÈoYg`...
@ :Left function
= : Reassign to U
#d : 100
Æ : Map the range [0,100)
£ : Map each X in U
BùX540 : Left pad B with X to length 540
ö : Select a random character
à : End inner map
à : End outer map
ñ : Sort by
èV : Count of elements that return truthy (non-empty string) when passed through function V (see below)
o : Pop the last element
) : End reassignment
Ê : Length
¶G : Is equal to variable G (see below)
} :End left function
a :Repeatedly run the right function then the left until the latter returns true
@ :Right function
N : Array of all inputs (initially empty)
p : Push
X+ : Append to the current 0-based iteration index
` : Compressed string
: : Literals
{ : Interpolate
¬ : U joined to a string
} : End interpolate
... : Compressed " -- score: "
{ : Interpolate
G= : Assign to variable G
Uè : Count of elements in U that return truthy
V= : Assign to variable V
È : Function taking a character string (X) and an index (Y) as arguments
o : Case insensitively keep the characters in X that appear in
Yg : Index Y into
`... : Compressed string "methinks it is like a weasel"
:Implicit output of N joined with newlines
Go, 453 bytes
import(."math/rand";."fmt")
func f() {T,A:="METHINKS IT IS LIKE A WEASEL","ABCDEFGHIJKLMNOPQRSTUVWXYZ "
S:=func(s string)(o int){for i:=range s{if s[i]==T[i]{o++}};return}
b:=""
for range 28{k:=Intn(len(A));b+=A[k:k+1]}
B:=S(b)
for r:=0;B<28;r++{l:=map[string]int{};for range 100{R:=[]byte(b);for i:=range R{if Float32()<0.05{k:=Intn(len(A));R[i]=A[k]}}
m:=string(R)
l[m]=S(m)}
for m,s:=range l{if B<=s{b,B=m,s}}
Printf("%2d: %s -- score: %d\n",r,b,B)}}
Semi-golfed explanation:
import(."math/rand";."fmt")
func f() {
// initial setup
target,alpha:="METHINKS IT IS LIKE A WEASEL","ABCDEFGHIJKLMNOPQRSTUVWXYZ "
// score function: higher == better
score:=func(s string)(o int){for i:=range s{if s[i]==target[i]{o++}};return}
// creates a new string
generate:=func()(s string){for range 28{k:=Intn(len(alpha));s+=alpha[k:k+1]};return}
// given a string, mutate it
mutate:=func(s string)string{r:=[]byte(s);for i:=range r{if Float32()<0.05{k:=Intn(len(alpha));r[i]=alpha[k]}};return string(r)}
best:=generate() // step 1: create a random string
bestScore:=score(best)
for round:=0;bestScore<28;round++{
// step 2: make 100 mutated copies
l:=map[string]int{}
for range 100{m:=mutate(best)
// step 3: score the strings
l[m]=score(m)
}
// find the new best
for m,s:=range l{if bestScore<=s{best,bestScore=m,s}}
// print best
Printf("%2d: %s -- score: %d\n", round, best, bestScore)
}
// step 4: halt on perfect score
// step 5: otherwise, go back to step 2
}
Japt, 98 bytes
;ªBiS ö28
=#dÆ£20ö ?X:BiS)öÃÃñL=_¬xȶYg`Ú0ks ¦ke a Øâel`u
mL o
=o
Op[T°+':X'-²`sÖ`W]¸
W<28©ß
Not a winner, but I really wanted to answer this fun challenge.
Perl 5, 219 bytes
$_="METHINKS IT IS LIKE A WEASEL";sub r{(A..Z,$")[rand 27]};sub t{~~grep/$t[$-++%28]/,pop=~/./g}$}.=r for@t=/./g;printf"%3d: %s -- score: %d
",$i++,(($})=sort{t($b)<=>t$a}map s/./rand>.05?$&:r/ger,($})x100),t$}until/$}/
Pyth, 116 bytes
Ls.bqNY"METHINKS IT IS LIKE A WEASEL"bj.e%"%d: %s -- score: %s"[ksbyb).W<yeH28+Z]eoyNmmO.[O+r1G\ k20eZ100]mO+r1G\ 28
Ls.bqNY"..."bj.e%"..."[ksbyb).W<yeH28+Z]eoyNmmO.[O+r1G\ k20eZ100]mO+r1G\ 28
L Define fitness function, y(b):
"..." The target string
.b b Map over characters of the above and b:
qNY Are they equal? True = 1, False = 0
s Take the sum
r1G The uppercase alphabet
+ \ Append a space
O Choose one at random
]m 28 Create an array of 28 of the above, wrap in array
.W Functional while, with above as initial value
Continue condition (current value = H):
eH Last value of H
y Apply fitness function to the above
< 28 Check the above is less than 28
Function body (current value = Z)
m eZ Map each character (as k) in the last value in Z over:
O+r1G\ Choose random char/space (as above)
.[ k20 Pad the above to length 20 using k
O Choose one of the above at random
m 100 Do the above 100 times
oyN Order the above by the fitness function
]e Take the last of the above, wrap in array
+Z Append to Z
Return value of while is array of all steps taken
.e Map each entry with its index over:
k Current index
sb Current entry joined on empty string
yb Fitness of current entry
[ ) Wrap the above 3 results in an array
%"..." String formatting using the output string
j Join on newlines, implicit output
JavaScript (Node.js), 328 bytes
t="METHINKS IT IS LIKE A WEASEL";z=0;m=Math.random;r=_=>(n=0|27*m())?String.fromCharCode(64+n):" ";for(s="";28>s[l="length"];s+=r())for(;28>z;){for(a=[s];100>a[l];){for(x="";28>x[l];)x+=.95<=m()?r():s.substr(x[l],1);a.push(x)}for(i=0;100>i;i++){for(j=b=0;28>j;j++)b+=a[i][j]==t[j];b>z&&(alert(a[i]+" -- score: "+b),z=b,s=a[i])}}
This is rather long and can be shortened, just haven't gotten around to that.
Explanation :
This is not exactly an explanation but it is better indented and can
t = "METHINKS IT IS LIKE A WEASEL";
z = 0;
m = Math.random;
r = _ => (n = 0 | 27 * m()) ? String.fromCharCode(64 + n) : " ";
for (s = ""; 28 > s[l = "length"]; s += r())
for (; 28 > z;) {
for (a = [s]; 100 > a[l];) {
for (x = ""; 28 > x[l];) x += .95 <= m() ? r() : s.substr(x[l], 1);
a.push(x)
}
for (i = 0; 100 > i; i++) {
for (j = b = 0; 28 > j; j++) b += a[i][j] == t[j];
b > z && (alert(a[i] + " -- score: " + b), z = b, s = a[i])
}
}
Japt v2.0a0, 112 108 bytes
ª(T=Si26õdI q¹ö28
_¬í¥`Ú0ks ¦ke a Øâel`u q)x
(OpW+`: {U} -- sÖ: `+(K=[U]xV¹WÄ
K<28©ßLÆ®p513 iT ö}ÃñV o
-4 bytes thanks to @ETHproductions.
Unpacked & How it works
U||(T=Si26õdI q) ö28 Initialize primary input
U|| If U is not initialized...
26õdI Generate uppercase alphabets
q Convert to string
Si Add space
(T= ) Assign to variable T
ö28 Sample 28 random chars from T and form a string
Implicitly assign to U
_q í==`Ú0ks ¦ke a Øâel`u q)x Match counting function
_ Declare a function...
q í== ) Convert to array of chars and pair with the next,
and map with equality...
`Ú0ks ¦ke a Øâel`u q "methinks it is like a weasel" to uppercase
split into chars
x Sum (true == 1, false == 0)
Implicitly assign to V
(OpW+`: {U} -- sÖ: `+(K=[U]xV) W+1 Output and increment counter
(Op ) Output with newline...
W+`: {U} -- sÖ: `+ `{W}: {U} -- score: `
[U]xV Call V on [U] and force cast to number
(K= ) Assign to K
W+1 Add 1 to W and implicitly assign to W
K<28&&ßLo@Um_p513 iT ö}} ñV o Termination check and recursion
K<28&& If the match count is less than 28...
ß Recurse the program with...
Um_ Map over chars of U...
p513 iT The char repeated 513 times plus T
ö} Sample a char from it
Lo@ } Generate array of 100 of the above
ñV o Sort by V, pop the largest, pass it as U
Ruby, 206 200 199
q,i,*R=*-2..27
puts"#{i+=1}: #{$.,s=(-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=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 2nd 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=(-2..q).map{...}.max;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
Ruby - 225 202 203 198 chars
Ruby seems under-represented in this challenge so far so I thought I would give it a try! Improvements welcome.
g=-1
s=[]
puts"#{g+=1}: #{$.,s=(0..99).map{n=(r=0..27).map{|i|x=[' ',*?A..?Z].sample;rand<0.05?x:s[i]||=x};[r.count{|i|n[i]=='METHINKS IT IS LIKE A WEASEL'[i]},n*'']}.max;s} -- score: #$."until$.>27
Julia, 281 bytes
Golfed:
r=n->['A':'Z',' '][rand(1:27,n)]
s=a->sum(a.=="METHINKS IT IS LIKE A WEASEL".data)
p=(z,a,s)->println(z,": ",join(a)," -- score: ",s)
a = r(28)
b = s(a)
z = 0
p(z,a,b)
while b<28
c=b
d=a
for i=1:100
e=[rand()<.95?i:r(1)[1]for i=a]
f=s(e)
if(f>c)
c=f
d=e
end
end
a=d
b=c
p(z,a,b)
z+=1
end
The algorithm itself isn't very clever, but there are some cool bits in here. Combining a character range with another character, then indexing into it: ['A':'Z',' '][rand(1:27,n)] and taking the sum of an array of booleans (common, but I still love the idea): sum(a.=="METHINKS IT IS LIKE A WEASEL".data). Glad I got under 300!
Ungolfed:
randchar = n -> ['A':'Z',' '][rand(1:27,n)]
score = a -> sum(a.=="METHINKS IT IS LIKE A WEASEL".data)
myprint = (z,a,s) -> println(z,": ",join(a)," -- score: ",s)
currentarray = randchar(28)
currentscore = score(currentarray)
z = 0
myprint(z,currentarray,currentscore)
while currentscore < 28
bestscore = currentscore
bestarray = currentarray
for i = 1:100
temparray = [rand()<.95?i:randchar(1)[1]for i=currentarray]
tempscore = score(temparray)
if(tempscore > bestscore)
bestscore = tempscore
bestarray = temparray
end
end
currentarray = bestarray
currentscore = bestscore
myprint(z,currentarray,currentscore)
z+=1
end
C++ 668
Not really short, but the only one in c++. (:
#include "stdafx.h"
using namespace std;int _tmain(){srand(time(NULL));string z="METHINKS IT IS LIKE A WEASEL";string a(28,' ');for(int i=0;i<28;++i){a[i]='A'+(rand()%26);}while(1){vector<std::pair<int,string>>d;for(int i=0;i<100;++i){d.push_back(std::pair<int,string>(0,""));for(int j=0;j<28;++j){int b=rand()%100;if(b<6){if(b<2){d[i].second+=' ';}else{d[i].second+='A'+(rand()%26);}}else {d[i].second+=a[j];}}}for(int i=0;i<100;++i){for(int j=0;j<28;++j){if(d[i].second[j]==z[j]){d[i].first++;}}}int y=0;for(int i=0;i<100;++i){if(d[i].first==28){cout<<d[i].second<<" "<<d[i].first;exit(1);}else if(d[i].first>y){y=d[i].first;a=d[i].second;}}cout<<a<<" "<<y<<endl;}}
more readable version:
#include "stdafx.h"
#include <string>
#include <stdlib.h>
#include <vector>
#include <iostream>
#include <time.h>
using namespace std;
int _tmain()
{
srand(time(NULL));
string z = "METHINKS IT IS LIKE A WEASEL";
string a(28, ' ');
for (int i = 0; i < 28; ++i)
{
a[i] = 'A' + (rand() % 26);
}
while(1)
{
vector<std::pair<int, string >> d;
for (int i = 0; i < 100; ++i)
{
d.push_back(std::pair<int, string>(0, ""));
for (int j = 0; j < 28; ++j)
{
int b = rand() % 100;
if (b < 6)
{
if (b < 2)
{
d[i].second += ' ';
}
else {
d[i].second += 'A' + (rand() % 26);
}
}
else {
d[i].second += a[j];
}
}
}
for (int i = 0; i < 100; ++i)
{
for (int j = 0; j < 28; ++j)
{
if (d[i].second[j] == z[j])
{
d[i].first++;
}
}
}
int y = 0;
for (int i = 0; i < 100; ++i)
{
if (d[i].first == 28)
{
cout << d[i].second << " " << d[i].first;
exit(1);
}
else if (d[i].first > y)
{
y = d[i].first;
a = d[i].second;
}
}
cout << a << " " << y << endl;
}
}
Output:
VEBVTEWX CEWMYLTAJTYPFYYXBDQ 2
EBVTEWX CEWMYLTAJT PFYYXBDQ 3
EBVTEKX CEWMYLTAJT PFYYXBDQ 4
EBVTEKX CEWM TAJT PFYYXBDQ 5
EBVTEKX CE M TAJT P YYX DQ 7
MEPVTEKX CE M TAJT P YY D 8
MEPVT KX CE M TAJT A YY D 9
MEPVI KX CE M UAJT A YY D 10
MEPSI KX CE M UAJT A YY D 10
MEPSI K CE M UAJE A YY DE 11
MEPSI K CE M UAJE A YY DL 12
MEPPI K CE I UDJE A YY DL 13
MEPRI K CE IS UDJE A YY DL 14
MEPRI K CE IS UDJE A Y DL 14
MEPHI K CE IS UDJE A Y DL 15
MEPHI K CE IS UDJE A Y DL 15
MEPHI K CE IS RDBE A E DL 16
MEPHIQK CE IS RD E A E DL 16
MEPHIQK CE IS RD E A E DL 16
ME HIQK CE IS RDXE A E DL 16
ME HIQK CE IS W XE A E DL 16
ME HIQK CE IS W XE A E EL 17
ME HIQK CE IS W XE A E EL 17
ME HIQK CE IS XE A E EL 17
MEGHIQK CE IS XE A WEO EL 18
MEGHIQK CE IS XE A WEO EL 18
MEGHIQK CE IS XE A WEO EL 18
MEGHIQK CE IS XE A WE EL 18
MEGHIQK CE IS XE A WE SEL 19
MEGHIQK CE IS L XE A WE SEL 20
MEGHINK CE IS L XE A WE SEL 21
MEGHINK CE IS L XE A WE SEL 21
MEGHINK CN IS L XE A WEASEL 22
MEGHINK H IS L XE A WEASEL 22
MEGHINK H IS L XE A WEASEL 22
METHINK H IS L XE A WEASEL 23
METHINK H IS L XE A WEASEL 23
METHINK H IS L XE A WEASEL 23
METHINK H IS L XE A WEASEL 23
METHINK H IS L XE A WEASEL 23
METHINK H IS L XE A WEASEL 23
METHINK ZH IS L XE A WEASEL 23
METHINK ZH IS LIXE A WEASEL 24
METHINK ZH IS LIKE A WEASEL 25
METHINKD ZH IS LIKE A WEASEL 25
METHINKD ZH IS LIKE A WEASEL 25
METHINKD ZH IS LIKE A WEASEL 25
METHINKD ZH IS LIKE A WEASEL 25
METHINKD ZT IS LIKE A WEASEL 26
METHINKD ZT IS LIKE A WEASEL 26
METHINKD ZT IS LIKE A WEASEL 26
METHINKS ZT IS LIKE A WEASEL 27
METHINKS IT IS LIKE A WEASEL 28
Python 2.7 - 319 bytes
Sure it's not the smallest, but it was fun to program.
from random import*
a=map(chr,range(65,91))+[' ']
c,i,y=choice,0,{}
s=[c(a)for i in[0]*28]
while 1:
for j in[0]*100:v=[c(a)if .05>random()else x for x in s];y[sum(1if'METHINKS IT IS LIKE A WEASEL'[k]==v[k]else 0for k in range(28))]=v
v=max(y.keys());s=y[v];print"%d: %s -- score: %d"%(i,''.join(y[v]),v);i+=1
if v==28:break
Uses a recursing function, so it may reach the maximum recursion depth if there is some kind of weird devolution with the string.
ubuntu@ubuntu-OptiPlex-980:~$ python weasel.py
0: VPBHBSPWFTOG HAXSESCDNFPKWYE -- score: 1
1: VABHBSPWFTOG HAXSESCDNWPKWYE -- score: 2
2: VAWHBSPWFTOGIHAXSESSDNWPKWYE -- score: 3
3: VAWHBSPWFTOGIHAXSEFSGNWPKWYL -- score: 4
4: XAWHBSPYFTOGIHAXSEFSGNWPKWYL -- score: 4
5: XAWHBSKYFTOGIHAXSEFSGNWPKWYL -- score: 5
6: XAWHBSKYFTOGIHAXSEF GNWPKWYL -- score: 6
7: XAWHBSKYFTOGIHALSEF ANWPKWYL -- score: 8
8: XAKHBSKYFTTGIHALSEY ANWPKWYL -- score: 9
9: XAKHISKYFTTGIHALSEE ANWPKWYL -- score: 11
10: XAKHISKSFTTGIHALSEE ANWPKWYL -- score: 12
11: XAKHISKSFTTGIHALSBE ANWPKWKL -- score: 12
12: XAQHISKSFRT IHALSBE ANWPKWKL -- score: 13
13: XAQHISKSFIT IHALSBE ANWPKWKL -- score: 14
14: XAQHISKSFIT IHALSBE ANWPKWKL -- score: 14
15: XAQHISKSFIT IHALSBE ANWPKWKL -- score: 14
16: XALHISKSFIT ISALSBE ANWPKWKL -- score: 15
17: JALHISKSFIT ISALSBE ANWPAWKL -- score: 16
18: JALHISKSFIT ISALIBE ANWPAWKL -- score: 17
19: JALHISKSFIT ISALIBE ANWPAWKL -- score: 17
20: JALHISKSFIT ISALIBE ANWPAWKL -- score: 17
21: JALHISKSFIT ISALIKE ANWPAWYL -- score: 18
22: JALHISKSFIT IS LIKE ANWPAWYL -- score: 19
23: JALHISKSFIT IS LIKE ANWEAWYL -- score: 20
24: JALHISKSFIT IS LIKE ANWEAWYL -- score: 20
25: JALHISKSFIT IS LIKE ANWEAWZL -- score: 20
26: JALHISKS IT IS LIKE ANWEAAZL -- score: 21
27: JACHISKS IT IS LIKE ANWEASZL -- score: 22
28: JACHISKS IT IS LIKE ANWEASZL -- score: 22
29: MACHISKS IT IS LIKE ANWEASZL -- score: 23
30: MACHISKS IT IS LIKE ANWEASZL -- score: 23
31: MACHISKS IT IS LIKE AUWEASZL -- score: 23
32: MACHISKS IT IS LIKE AUWEASZL -- score: 23
33: MACHISKS IT IS LIKE AJWEASZL -- score: 23
34: MACHISKS IT IS LIKE A WEASZL -- score: 24
35: MACHISKS IT IS LIKE A WEASZL -- score: 24
36: MACHINKS IT IS LIKE A WEASZL -- score: 25
37: MACHINKS IT IS LIKE A WEASZL -- score: 25
38: MACHINKS IT IS LIKE A WEASZL -- score: 25
39: MBCHINKS IT IS LIKE A WEASZL -- score: 25
40: MBCHINKS IT IS LIKE A WEASZL -- score: 25
41: MBCHINKS IT IS LIKE A WEASZL -- score: 25
42: MBCHINKS IT IS LIKE A WEASZL -- score: 25
43: MBCHINKS IT IS LIKE A WEASZL -- score: 25
44: MBCHINKS IT IS LIKE A WEASZL -- score: 25
45: MECHINKS IT IS LIKE A WEASCL -- score: 26
46: MECHINKS IT IS LIKE A WEASCL -- score: 26
47: MECHINKS IT IS LIKE A WEASCL -- score: 26
48: MECHINKS IT IS LIKE A WEASCL -- score: 26
49: MECHINKS IT IS LIKE A WEASCL -- score: 26
50: MECHINKS IT IS LIKE A WEASCL -- score: 26
51: MEQHINKS IT IS LIKE A WEASCL -- score: 26
52: MEQHINKS IT IS LIKE A WEASCL -- score: 26
53: MEQHINKS IT IS LIKE A WEASCL -- score: 26
54: MEQHINKS IT IS LIKE A WEASCL -- score: 26
55: MEQHINKS IT IS LIKE A WEASCL -- score: 26
56: MEQHINKS IT IS LIKE A WEASCL -- score: 26
57: METHINKS IT IS LIKE A WEASCL -- score: 27
58: METHINKS IT IS LIKE A WEASCL -- score: 27
59: METHINKS IT IS LIKE A WEASCL -- score: 27
60: METHINKS IT IS LIKE A WEASCL -- score: 27
61: METHINKS IT IS LIKE A WEASCL -- score: 27
62: METHINKS IT IS LIKE A WEASCL -- score: 27
63: METHINKS IT IS LIKE A WEASCL -- score: 27
64: METHINKS IT IS LIKE A WEASCL -- score: 27
65: METHINKS IT IS LIKE A WEASEL -- score: 28
Massive thanks to Sp3000 for golfing help.
Racket: 426 422 bytes
(let*((r random)(m map)(L" ABCDEFGHIJKLMONPQRSTUVWXYZ")(P(string->list"METHINKS IT IS LIKE A WEASEL"))(c(λ(l p)(m(λ(x)(if(<(r)p)(string-ref L(r 27))x))l)))(s(λ(l P p)(cons(foldl(λ(x y a)(if(eqv? x y)(+ a 1)a))0 l P)l))))(let r((g 0)(o (c P 1)))(let*((o(sort(m(λ(x)(s(c o 0.05)P 0))(range 100))(λ g(apply >(m car g)))))(p(caar o))(c(cdar o)))(printf"~a: ~a -- score: ~a
"g(list->string c)p)(if(= p 28)p(r(+ g 1)c)))))
Ungolfed:
(let* ((r random)
(m map)
(L " ABCDEFGHIJKLMONPQRSTUVWXYZ")
(P (string->list "METHINKS IT IS LIKE A WEASEL"))
(c (λ (l p)
(m (λ (x)
(if (< (r) p)
(string-ref L (r 27))
x))
l)))
(s (λ (l P p)
(cons (foldl (λ (x y a)
(if (eqv? x y)
(+ a 1)
a))
0
l
P)
l))))
(let r ((g 0) (o (c P 1)))
(let* ((o (sort (m (λ (x)
(s(c o 0.05)P 0))
(range 100))
(λ g
(apply >(m car g)))))
(p (caar o))
(c (cdar o)))
(printf"~a: ~a -- score: ~a\n" g (list->string c) p)
(if (= p 28)
p
(r (+ g 1) c)))))
Javascript (411 389 376)
Shorter than some, longer than most.. [Methinks it will end.] EDIT: it wasn't ending due to an error. fixed it and ended up dropping the count too -- cool.
t='METHINKS IT IS LIKE A WEASEL';z=0;m=Math.random;r=function(){n=Math.floor(m()*27);return n?String.fromCharCode(64+n):' '};for(s='';s.length<28;s+=r());while(z<28){a=[s];while(a.length<100){x='';while(x.length<28){x+=m()>=.95?r():s.substr(x.length,1)}a.push(x)}for(i=0;i<100;i++){b=0;for(j=0;j<28;j++){b+=a[i][j]==t[j]?1:0;}if(b>z){alert(a[i]+' -- score: '+b);z=b;s=a[i]}}};
expanded:
t = 'METHINKS IT IS LIKE A WEASEL';
z = 0;
m = Math.random;
r = function(){
n = Math.floor(m()*27);
return n ? String.fromCharCode(64+n) : ' '
};
for(s='';s.length<28;s+=r());
while( z < 28 ){
a = [s];
while( a.length < 100 ){
x = '';
while( x.length < 28 ){
x += m() >= .95 ? r() : s.substr(x.length, 1)
}
a.push(x)
}
for( i = 0; i < 100; i++ ){
b = 0;
for( j = 0; j < 28; j++ ){
b += a[i][j] == t[j] ? 1 : 0;
}
if( b > z ){
console.log( a[i] + ' -- score: ' + b);
z = b;
s = a[i]
}
}
};
[original:]
t='METHINKS IT IS LIKE A WEASEL';s='';z=0;m=Math.random;r=function(){n=Math.floor(m()*27);return n?String.fromCharCode(64+n):' '};c=function(){a=[s];while(a.length<100){x='';while(x.length<28){x+=m()>=.95?r():s.substr(x.length?x.length-1:0,1)}a.push(x)}for(i=0;i<100;i++){b=0;for(j=0;j<28;j++){b+=a[i][j]==t[j]?1:0;}if(b>z){alert(a[i]+' -- score: '+b);z=b;s=a[i]}i++}};while(s.length<28){s+=r()}while(z<28){c()}
Ruby, 218
g,s,p,t=-1,'',1;while t!=28;t,b=-1;100.times{|i|m,n='',0
28.times{|j|n+=1if(m[j]=(rand<p ?[*?A..?Z,' '].sample: s[j]))=="METHINKS IT IS LIKE A WEASEL"[j]}
b,t=m,n if n>t};puts"#{g+=1}: #{s=b} -- score: #{t}";p=0.05;end
example run
0: LRAZZMKL IKUOGEHLKPWEVNEAZWX -- score: 6
1: LRAZZMKL IKUIGEALKMWEVNEAZWX -- score: 7
2: HRAGZMKL IKUIGEALKMWEVNEAZWX -- score: 7
3: HVAGZMKL IKUISAALKYWEVNEAZWX -- score: 8
...
48: METHIUKS IT IS LIKEIA WEASEL -- score: 26
49: METHINKS IT IS LIKEIA WEASEL -- score: 27
50: METHINKS IT IS LIKEIA WEASEL -- score: 27
51: METHINKS IT IS LIKE A WEASEL -- score: 28
Haskell - 420 characters
This is more verbose than most; I'd put that down to my inexperience with randomness in haskell and proper use of monads.
import System.Random
r=randomRIO
z=zipWith
c=fmap((' ':['A'..'Z'])!!)$r(0,26)
y=(i.).replicate
i=mapM id
s=sum.z((fromEnum.).(==))"METHINKS IT IS LIKE A WEASEL"
u a n|n==0=c|True=return a
b n a|s n>s a=n|True=a
g=fmap(foldr1 b).y 100.mapM((r(0,20)>>=).u)
e x=do n<-g$x!!0;if(s$x!!0)==28 then return(n:x)else e(n:x)
main=y 28 c>>=(\a->e[a])>>=(i.z(\n x->putStrLn$shows n$": "++x++" -- score: "++(show$s x))[0..]).reverse
Scala, 347 341 337 chars:
import util.Random.{nextInt=>r}
val t="METHINKS IT IS LIKE A WEASEL"
def c="ABCDEFGHIJKLMNOPQRSTUVWXYZ "(r(27))
def s(a:String)=t.zip(a).map{x=>if(x._1==x._2) 1 else 0}.sum
def w(a:String,i:Int=0){println(f"$i%2d: $a -- score: ${s(a)}")
if(s(a)!=28){w((0 to 99).map{_=>a.map(o=>if(r(20)<1) c else o)}.sortBy(s).last,i+1)}}
w(t.map(_=>c))
=>
0: PGSHWAEPALQFTCORUKANPNUTRVXH -- score: 2
1: PGSHWAEPALQ TCOQUKANPNUTRVXH -- score: 3
...
47: METHINKS WT IS LIKE A WEASEL -- score: 27
48: METHINKS IT IS LIKE A WEASEL -- score: 28
Groovy: 314
def(r,o,g)=[new Random(),{(0..27).sum{x->"METHINKS IT IS LIKE A WEASEL"[x]==it[x]?1:0}},0]
def q={([' ']+('A'..'Z'))[r.nextInt(27)]}
def s=q()*28
for(;;){println"${g++}: $s -- score: ${o(s)}"
if(o(s)==28)break
s=([s]*100).collect{it.collect{5>r.nextInt(100)?q():it}.sum()}.groupBy{o(it)}.max{it.key}.value[0]}
Output:
0: -- score: 5
1: B S -- score: 6
2: E B S M -- score: 7
3: E B S M -- score: 7
4: E BT X S M -- score: 8
...
68: METHINKS IT IS LIKE L WEASEL -- score: 27
69: METHINKS IT IS LIKE L WEASEL -- score: 27
70: METHINKS IT IS LIKE L WEASEL -- score: 27
71: METHINKS IT IS LIKE L WEASEL -- score: 27
72: METHINKS IT IS LIKE A WEASEL -- score: 28
I feel like this is cheating so I'm not counting it as my 'real' answer; but I can save a few chars by passing "METHINKS IT IS LIKE A WEASEL" and " -- score: " as arguments to my script. Although technically it is 'externalizing strings'... which everyone knows is good practice :).
Groovy: 290
def(r,o,g)=[new Random(),{(0..27).sum{x->args[0][x]==it[x]?1:0}},0]
def q={([' ']+('A'..'Z'))[r.nextInt(27)]}
def s=q()*28
for(;;){println"${g++}: $s${args[1]}${o(s)}"
if(o(s)==28)break
s=([s]*100).collect{it.collect{5>r.nextInt(100)?q():it}.sum()}.groupBy{o(it)}.max{it.key}.value[0]}
Run like groovy script.groovy "METHINKS IT IS LIKE A WEASEL" " -- score: "
C 331
Another C solution that comes out to 331 characters. I think I might be able to improve it if I look a bit closer. Anyway the solution follows:
char l[29],b[29],*a="ABCDEFGHIJKLMNOPQRSTUVWXYZ ",i,j,*t="METHINKS IT IS LIKE A WEASEL",s,m=0;main(){for(i=0;i<28;i++)l[i]=a[rand()%27];while(strcpy(l,b))for(i=0;i<100;i++){for(j=s=0;j<28;j++){if(rand()%20==0)l[j]=a[rand()%27];if(l[j]==t[j])s++;}printf("%s -- score: %d\n",l,s);if(s>m){m=s;strcpy(b,l);}if(!strcmp(b,t))goto e;}e:;}
PHP (381 397 323 319 312):
<? function s(&$s,&$i=0){$t='METHINKS IT IS LIKE A WEASEL';$i=0;$c=$s;$f=28;while($f--){$n=rand(0,26);$i+=($s[$f]=($c=='_'||!rand(0,19)?chr($n?$n+64:32):$s[$f]))==$t[$f];}}$s='_';s($s);$x=$y=0;do{$f=100;while($f--){$m=$s;s($m,$i);if($i>$y){$y=$i;$l=$m;}}printf("%2d: %s -- score: $y\n",$x++,$s=$l);}while($y<28);
Readable version:
<?
function s(&$s, &$i = 0) {
$t = 'METHINKS IT IS LIKE A WEASEL';
$i = 0;
$c = $s;
$f = 28; while ($f--) {
$n = rand(0, 26);
$i += ($s[$f] = ($c == '_' || !rand(0, 19) ? chr($n ? $n + 64 : 32) : $s[$f])) == $t[$f];
}
}
$s = '_';
s($s);
$x = $y = 0;
do {
$f = 100; while ($f--) {
$m = $s;
s($m, $i);
if ($i > $y) {
$y = $i;
$l = $m;
}
}
printf("%2d: %s -- score: $y\n", $x++, $s = $l);
} while ($y < 28);
Optimization credits (319):
- @GigaWatt in this comment
- @Einacio for !rand(0,19) taken from here
Optimization credits (312):
- @Einacio's comments
R, 291 characters
Longer than the previously proposed R answer but significantly different to be (I think) of interest:
a=sample;b=a(c<-c(LETTERS,' '),28,T);d=0;h=function(x)sum(x==strsplit("METHINKS IT IS LIKE A WEASEL",'')[[1]]);while(h(b)!=28){if(d){f=replicate(100,{e=runif(28)>.05;S=a(c,28,T);S[e]=b[e];S});g=f[,which.max(apply(f,2,h))];if(h(g)>h(b))b=g};cat(d,': ',b,' -- score: ',h(b),'\n',sep='');d=d+1}
With indentations:
a=sample
b=a(c<-c(LETTERS,' '),28,T)
d=0
h=function(x)sum(x==strsplit("METHINKS IT IS LIKE A WEASEL",'')[[1]])
while(h(b)!=28){
if(d){
f=replicate(100,{e=runif(28)>.05;S=a(c,28,T);S[e]=b[e];S})
g=f[,which.max(apply(f,2,h))]
if(h(g)>h(b))b=g
}
cat(d,': ',b,' -- score: ',h(b),'\n',sep='')
d=d+1
}
Outputs:
0: OUZ IT HNGNMSKIHSMCQUGXTOYVZ -- score: 1
1: OUZ IT HNGNMSKYHSMCQUGWXOYVZ -- score: 2
2: OUZ IT HNGNMSKYLSMCQUGWXOYVZ -- score: 3
3: OUZ IT HNGNMSKYLSMC UGWXOYVZ -- score: 4
...
68: METHINKS IT ES LIKE A WEASEL -- score: 27
69: METHINKS IT ES LIKE A WEASEL -- score: 27
70: METHINKS IT IS LIKE A WEASEL -- score: 28
The key here is the line f=replicate(100,{e=runif(28)>.05;S=a(c,28,T);S[e]=b[e];S}):
e=runif(28)>.05 draws randomly 28 numbers between 0 and 1 on a uniform distribution, and gives TRUE if over 5% and FALSE if under 5%. S=a(c,28,T) draws 28 new letters/spaces, while S[e]=b[e] replaces those for which the value was over 5% by the corresponding letter from the previous generation (i .e. those for which the value was less than 5% are therefore new).Then we replicate the operation 100 times.
On the following line (g=f[,which.max(apply(f,2,h))]) we compute the score for each of the 100 replicates and keep the one that has the maximum score (in case of equality the first one is kept) to be compared with the previous generation.
C 361 331
Not as good as Art's solution, but here's my (newbie) attempt at a C solution. 361 characters if you remove newlines and tabs.
char*w="METHINKS IT IS LIKE A WEASEL";char b[101][29];t,s,n,i,j,x,a;main(){for(;i<28;i++)b[0][i]=w[rand()%28];while(s<28){for(j=1;j<101;j++){x=0;for(i=0;i<28;i++){if(!(rand()%20))b[j][i]=w[rand()%28];else b[j][i]=b[0][i];if(b[j][i]==w[i])x++;}if(x>s){s=x;t=j;}}printf("%d: %s -- score %d\n",n++,b[t],s);for(;i>=0;--i){a=b[0][i];b[0][i]=b[t][i];b[t][i]=a;}t=0;}}
Edit: Got rid of the nested loop and used a 1D array. Was hoping it would make a bigger difference, but it only saved me 30 characters. Here's the code:
char*w="METHINKS IT IS LIKE A WEASEL";char b[2929];t,s,n,i,x;main(){for(;i<28;i++)b[i]=w[rand()%28];while(s<28){for(;i<2929;i++){if((i+1)%29){if(!(i%29))x=0;b[i]=rand()%20?b[i%29]:w[rand()%28]; x+=b[i]==w[i%29];if(x>s){s=x;t=i/29;}}}for(i=0;i<29;i++){x=b[i+t*29];b[i+t*29]=b[i];b[i]=x;}printf("%d: %s -- score %d\n",n++,b,s);t=0;}}
Edit: This is the original, ungolfed code, for those who are interested in knowing how the "golfing" was done. The code produces no warnings when compiled with GCC with -Wall and C99 enabled. Maybe you're a golfing newbie like me, or a C newbie like me, or maybe you're just curious. :) https://gist.github.com/cpx/97edbce4db3cb30c306a
Python (330 321)
def b(i,s):print i,':',''.join(s),'-- score:',p(s)
from random import*;a=" ABCDEFGHIJKLMNOPQRSTUVWXYZ";i,s,t=0,choice(a)*28,"METHINKS IT IS LIKE A WEASEL";p=lambda n:sum(n[c]==t[c]for c in range(28))
while p(s)<28:b(i,s);s=sorted([[(c,choice(a))[random()<.05]for c in s]for k in[1]*100],key=lambda n:p(n))[-1];i+=1
b(i,s)
Readable version:
def b(i,s):
print i,':',''.join(s),'-- score:',p(s)
import random as r
a=" ABCDEFGHIJKLMNOPQRSTUVWXYZ"
i,s,t=0,r.choice(a)*28,"METHINKS IT IS LIKE A WEASEL"
p=lambda n:sum(1for c in range(28)if n[c]==t[c])
while p(s)<28:
b(i,s)
s=sorted([[(c,r.choice(a))[r.random()<.05]for c in s]for k in[1]*100],key=lambda n:p(n))[-1];i+=1
b(i,s)
Example output:
0 : SSSSSSSSSSSSSSSSSSSSSSSSSSSS -- score: 3
1 : SSSQSSSSSSSSSSSSISSSSSSSSSSS -- score: 4
2 : SSSQISSSSSSSSSSSISSSSSSSSSSS -- score: 5
3 : SSSQISSSSSSSSSSSIKSSSSSSSSSS -- score: 6
4 : SMSQISSSSSSSISSSIKSSSSGSSSSS -- score: 7
...
53 : METHINKS IT IS UIKE A WEASEL -- score: 27
54 : METHINKS IT IS UIKE A WEASEL -- score: 27
55 : METHINKS IT IS LIKE A WEASEL -- score: 28
edit: removed a few characters based on AMKs and Timtechs answer
Golfscript (168 167)
:x;0['METHINKS IT IS LIKE A WEASEL'{}/]:o{;{27rand.!96*+64^}:r~}%{o=!}{100,{;.{20rand{}{;r}if}%}%{{[o\]zip{~=},,}:s~}$)@;\;x 2$+': '+1$+' -- score: '+1$s+n+:x;\)\}/;;x
Sadly, I can't seem to compress it quite to APL's level, but it's afaict currently a shared second place.
This is what it does;
# Grab the empty parameter string as initially empty output string.
:x;
# Start count at row #0
0
# Store the target string as an array in 'o'
['METHINKS IT IS LIKE A WEASEL'{}/]:o
# Create a random starting string, and define 'r' as a function generating a random char.
{;{27rand.!96*+64^}:r~}%
# Unfold as long as the latest string is different from the target string.
{o=!}
{
// Generate 100 strings, sort by score and keep the highest.
100,{;.{20rand{}{;r}if}%}%{{[o\]zip{~=},,}:s~}$)@;\;
// Append the row to the output string, and increase the row number
x 2$+': '+1$+' -- score: '+1$s+n+:x;\)\
}/
// Clean some junk on the stack
;;
// Output string
x
PHP 429 426 421 415
<? function t(){$a="ABCDEFGHIJKLMNOPQRSTUVWXYZ ";return $a{rand(0,26)};}$c='';$j=$g=0;$i=28;while($i--)$c.=t();function r($s){$i=28;while($i--)!rand(0,19)&&$s{$i}=t();return $s;}function s($s,&$r){$c="METHINKS IT IS LIKE A WEASEL";$i=28;$r=0;while($i--)$r+=$s{$i}==$c{$i};}while($g<28){$n='';$v=0;$i=100;while($i--){s($t=r($c),$a);($a>$v)&&($v=$a)&($n=$t);}($v>$g)&&($g=$v)&($c=$n);echo $j++.": $c -- score: $g\n";}
pretty print
<?php
function t(){
$a="ABCDEFGHIJKLMNOPQRSTUVWXYZ ";
return $a{rand(0,26)};
}
$c='';
$j=$g=0;
$i=28;
while($i--)
$c.=t();
function r($s){
$i=28;
while($i--)
!rand(0,19)&&$s{$i}=t();
return $s;
}
function s($s,&$r){
$c="METHINKS IT IS LIKE A WEASEL";
$i=28;
$r=0;
while($i--)
$r+=+($s{$i}==$c{$i});
}
while($g<28){
$n='';
$v=0;
$i=100;
while($i--){
s($t=r($c),$a);
($a>$v)&&($v=$a)&($n=$t);
}
($v>$g)&&($g=$v)&($c=$n);
echo $j++.": $c -- score: $g\n";
}
I'll need a less verbose language next time
Python: 282 characters no semi colons
from random import*
g,r,l,c=0,0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ ",choice
k=map(c,[l]*28)
while(r!=28):
r,k=max((sum(i==j for i,j in zip(t,"METHINKS IT IS LIKE A WEASEL")),t)for t in[[c(l)if random()<.05 else i for i in k]for i in[1]*100])
print`g`+":","".join(k),"-- score:",`r`
g+=1
278 with:
from random import*;g,r,l,c=0,0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ ",choice;k=map(c,[l]*28)
while(r!=28):r,k=max((sum(i==j for i,j in zip(t,"METHINKS IT IS LIKE A WEASEL")),t)for t in[[c(l)if random()<.05 else i for i in k]for i in[1]*100]);print`g`+":","".join(k),"-- score:",`r`;g+=1
C 256
char c[101][29],s,n,z,b,j,i,w;g;main(){for(;w<28;printf("%d: %s -- score: %d\n",g++,c[b=n],w))for(i=w=0;i<101;i++)for(s=j=0;j<28&&!(i==b&&g);j++)(s+=(c[i][j]=g&&rand()%20?c[b][j]:(z=rand()%27)?'A'+z-1:' ')=="METHINKS IT IS LIKE A WEASEL"[j])>w?n=i,w=s:0;}
Simple three loops, initialization, generation of new strings from parent and score calculated by the same statement. It's not very readable even with indentation.
C 252
i,g,n,b,o,s,w,z;char c[2929];main(){for(;(o=i%29)|i|w<28;(i=(i+1)%2929)||printf("%d: %s -- score: %d\n",g++,&c[b=n],w))(s+=o>27?-s:((i-o!=b||!g)&&(c[i]=g&&rand()%20?c[b+o]:(z=rand()%27)?'A'+z-1:' ')=="METHINKS IT IS LIKE A WEASEL"[o]))>w?n=i-o,w=s:0;}
One loop, with one array holding all 101 strings.
This second version breaks the rules because it prints the string from (the equivalent of) step 1, but it was either that or not print the last string. I'm stumped how to fix it without exploding in size. I'm posting it anyway for inspiration.
C 256
struct{char d[29];}p,t,n;i,j=-1,z,s,w,g;main(){for(;w<28;j>1&&printf("%d: %s -- score: %d\n",g++,(p=n).d,w))for(;j++%100;p=j?p:t)for(s=0,i=28;i--;)(s+=(t.d[i]=j&&rand()%20?p.d[i]:(z=rand()%27)?'A'+z-1:' ')=="METHINKS IT IS LIKE A WEASEL"[i])>w?n=t,w=s:0;}
Different approach, instead of making an array to hold 101 strings just regenerate the string 100 times and use struct assignment for easy copying. Initialization is done by starting the "repeat 100 times" counter at -1 and handling it carefully by strategically chosen post-increment. Despite a very different approach it ends up exactly the same as the first attempt - 256 characters.
Java: 557 534
enum W{W;public static void main(String[]a){char[]c=new char[28],h,d[];int i,k,e,s=W.s(c);for(i=0;i<28;i++)c[i]=W.r();for(i=0;;){W.p(i++,h=c,s);if(s>27)break;d=new char[100][28];for(char[]b:d){for(k=0;k<28;k++)b[k]=Math.random()<.05?W.r():h[k];if((e=W.s(b))>s){s=e;c=b;}}}}int s(char[]c){int s=0,k;for(k=0;k<28;k++)if(c[k]=="METHINKS IT IS LIKE A WEASEL".charAt(k))s++;return s;}void p(int i,char[]c,int s){System.out.println(i+": "+new String(c)+" -- score: "+s);}char r(){int i=(int)(Math.random()*27);return(char)(i==26?32:i+65);}}
Unwrapped:
enum W {
W;
public static void main(String[] a) {
char[] c = new char[28], h, d[];
int i, k, e, s = W.s(c);
for(i = 0; i < 28; i++)
c[i] = W.r();
for(i = 0;;) {
W.p(i++, h = c, s);
if(s > 27)
break;
d = new char[100][28];
for(char[] b : d) {
for(k = 0; k < 28; k++)
b[k] = Math.random() < .05 ? W.r() : h[k];
if((e = W.s(b)) > s) {
s = e;
c = b;
}
}
}
}
int s(char[] c) {
int s = 0, k;
for(k = 0; k < 28; k++)
if(c[k] == "METHINKS IT IS LIKE A WEASEL".charAt(k))
s++;
return s;
}
void p(int i, char[] c, int s) {
System.out.println(i + ": " + new String(c) + " -- score: " + s);
}
char r() {
int i = (int)(Math.random() * 27);
return (char)(i == 26 ? 32 : i + 65);
}
}
R (245 239 238 characters)
t=strsplit("METHINKS IT IS LIKE A WEASEL","")[[1]]
h=sample
s=h(f<-c(LETTERS," "),28,T)
c=0
while(!all(s==t)){for(i in 1:100){z=ifelse(runif(28)<.05,h(f,1),s)
y=sum(s==t)
if(sum(z==t)>y)s=z}
cat(c<-c+1,": ",s," -- score: ",y,"\n",sep="")}
Gives:
1: HSSSIMJM ETJISGBSCIELUYPLSED -- score: 7
2: HSSSIMJM ETJISGBSKIELUYPLSED -- score: 8
3: EETLITLM ETJISTBSKIELUYLLSEL -- score: 11
...
78: METHINKS IT IS LIKEEA WEASEL -- score: 27
79: METHINKS IT IS LIKEEA WEASEL -- score: 27
80: METHINKS IT IS LIKEEA WEASEL -- score: 27
81: METHINKS IT IS LIKE A WEASEL -- score: 28
JavaScript, 277 246
c=m=>" ABCDEFGHIJKLMNOPQRSTUVWXYZ"[0|Math.random()*m];for(s=[k=28];e=k;s[--k]=c(27));for(;alert(k+++": "+s.join("")+" -- score: "+e),e<28;s=t)for(z=100;f=0,z--;f>e&&(t=n,e=f))n=s.map((h,p)=>(h=c(540)||h,f+=h=="METHINKS IT IS LIKE A WEASEL"[p],h))
(requires arrow function support; indentation added only for readability)
// c() returns a random char using `m` as an index max
c=m=>" ABCDEFGHIJKLMNOPQRSTUVWXYZ"[0|Math.random()*m];
// generate base string `s`
for(s=[k=28];e=k;s[--k]=c(27));
// while score `e` is < 28
for(;alert(k+++": "+s.join("")+" -- score: "+e),e<28;s=t)
for(z=100;f=0,z--;f>e&&(t=n,e=f)) // do 100 mutations; keep best score
n=s.map((h,p)=>( // map `s` to `n` with 5% mutation
h=c(540)||h, // change the char in 5% of cases
f+=h=="METHINKS IT IS LIKE A WEASEL"[p], // score++ if char matches
h // arrow function return character
))
Feel free to change alert to console.log if you want a more pleasant execution experience.
There are some nifty golfy bits in here:
The function
creturns a random character from the alphabet string" ABC...". The function takes an argument to use as an upper bound for the random index selection. When generating the base string, we use27, so the function behaves normally.However, we abuse this behavior by asking for a random upper bound of 540 in
h = c(540) || h. Only 5% of the time willcactually return a string (because 540 * .05 = 27); the other 95% of the time, the randomly-chosen index falls beyond the length of the string, so the function returnsundefined. This falsey value causes a logical-OR cascade inc(540) || h, so the originalmapvaluehis used (i.e., no replacement occurs).The score-summing operation does
f+=h=="METHINKS IT IS LIKE A WEASEL"[p], which says "addtruetofif the currentmapcharacterhmatches thepth character of the WEASEL string". The number-plus-boolean addition coerces the boolean result to either0or1, which means thatfis incremented only when there is a match against the target WEASEL string.
JavaScript - 312
There is already a shorter JS solution above but it is using experimental pointer functions, so I thought I'd throw in another solution that is running in any JS environment:
for(r=Math.random,R=function(){return'METHINKS CODZAWFLBUGYQRXVJP'[~~(r()*27)]},_=[],_.$=n=0,D=function(s){for(c=[],c.$=i=0;i<28;){c[i]=s&&r()<.95?s[i]:R();_=(c.$+=c[i]=='METHINKS IT IS LIKE A WEASEL'[i++])>_.$?c:_};return c},D();_.$<28;){for(j=0;j++<1e2;)D(_);console.log(n+++': '+_.join('')+' -- score: '+_.$)}
Java (632)
class C {public static void main(String[] a){String b="AAAAAAAAAAAAAAAAAAAAAAAAAAAA";for(int i=1;;i++){String c=w(b);int s=s(c);if(s==28)break;if(s(b)<s){b=c;System.out.println(i+": "+c+" -- score: "+s);}}}public static String w(String b) {StringBuffer c = new StringBuffer(b);int max = 0;for (int i=0;i<100;i++){for(int j=0;j<28;j++)if(Math.random()<.06){double d=Math.random();c.setCharAt(j,(char)(d==1?32:d*26+65));}String d=c.toString();int s=s(d);if(s>max){max=s;b=d;}}return b;}public static int s(String s){String b="METHINKS IT IS LIKE A WEASEL";int sum=0;for(int j=0;j<28;j++)sum+=s.charAt(j)==b.charAt(j)?1:0;return sum;}}
Java is such a verbose language.. :(
SAS - 374
%macro r;ranuni(7)%mend;%macro s;r=int(%r*27);substr(x,t,1)=byte(ifn(r,64+r,32));%mend;%macro y;char(y,t)=char(x,t)%mend;options nonotes nosource;data x;length x$28;do t=1to 28;%s;end;y="METHINKS IT IS LIKE A WEASEL";do z=1by 1;o=x;do i=1to 100;c=0;x=o;do t=1to 28;if %r<=.05then do;%s;end;c+%y;end;if c>m then do;m=c;v=x;end;end;x=v;put z":" x"-- score:" m;if m<28;end;run;
->
1 :GUUVLNUSILSRZLRBXVVCWXX HXKC -- score:2
2 :MUUVLNUSILSRZLRBXVMCWXX HXKC -- score:3
3 :MUUVLNESILSRILRBXVMCWXX HXKC -- score:4
4 :MEUVLNESILSRIRRBXVMCWXX HXKC -- score:5
....
95 :METHINKS IT IS LIKE A XEASEL -- score:27
96 :METHINKS IT IS LIKE A XEASEL -- score:27
97 :METHINKS IT IS LIKE A XEASEL -- score:27
98 :METHINKS IT IS LIKE A WEASEL -- score:28
With linebreaks/indent/comments:
%macro r;
ranuni(7) /* seed 0 will make new each time (seed=clock), otherwise fixed results */
%mend;
%macro s; /* does the rand char, used both to initialize and replace; */
r=int(%r*27);
substr(x,t,1)=byte(ifn(r,64+r,32)); *r=0 becomes space otherwise upper char;
%mend;
%macro y; /*compares using new to 9.2 CHAR function which is equivalent to substr(str,start,1) */
char(y,t)=char(x,t)
%mend;
options nonotes nosource; /*cheapest way to get clean log */
data x;
length x$28; /*annoyingly necessary*/
do t=1to 28;%s;end; /*initialize string*/
y="METHINKS IT IS LIKE A WEASEL"; /*compare string */
do z=1by 1; /*start iterating */
o=x; /*save this iteration's string */
do i=1to 100;
c=0; /*score for this iteration*/
x=o; /*string to fudge about start out clean, reusing x so no params to macro*/
do t=1to 28;
if %r<=.05then do;%s;end; /*if 5% then change the char out */
c+%y; /*score that character*/
end;
if c>m then do; /*if on better scoring line, save it */
m=c;
v=x;
end;
end;
x=v; *for next iter - this is cheaper than other options involving o=v due to first iter;
put z":" x"-- score:" m;
if m<28; *quit at 28;
end;
run;
GolfScript 207
{91,{64>},32+''+27rand=}:g;'METHINKS IT IS LIKE A WEASEL':s;{`{\.@\=s@==}+s,,\%{+}*}:c;0:k;{k):k\.': '@@c' -- score: '\++++n+}:f;[{g}]28*{~}%{s=!}{{`100,\{\;{100rand 5>{ }{;g}if}%''+}+}~%{c}$)\;{ }%}/{f}/s f
Below is a slightly unpacked version of the above GolfScript with explanation. Since I don't think it could beat the APL or some other answers, I didn't bother to truly minify it. I think that with inlining variable declarations, eliminating unnecessary variables, and other such tricks, this code could achieve approximately 190 characters without really changing the algorithm. I think about about 10-15 characters could be removed if I better sorted out the conversion between arrays of ASCII values and strings.
#g is a function that returns the ASCII value of a random character or space.
#The ASCII values for capital letters are 65-90, and 32 is space.
{91,{64>},32+''+27rand=}:g;
#s is the string of interest.
'METHINKS IT IS LIKE A WEASEL':s;
#c is a function that returns the 'score' of a given string
#(the number of correct characters in the correct place).
{`{\.@\=s@==}+s,,\%{+}*}:c;
#t is a function that transforms a given string according to
#the specification (by replacing characters with a random character 5% of the times).
{{100rand 5>{ }{;g}if}%''+}:t;
#i is the initial random string.
[{g}]28*{~}%:i;
#Use '/' to unfold the initial value until the string is equal to the string of interest.
#Every loop, do the transformation 100 times, then sort by score c, and then take the top scoring string.
#Aggregate the results into an array a.
i{s=!}{{`100,\{\;t}+}~%{c}$)\;{ }%}/:a;
#Instantiate a counter variable k
0:k;
#f is the formatting function, that takes a string and formats it according to the spec.
{k):k\.': '@@c' -- score: '\++++n+}:f;
#Format every string in the array, and then format the string of interest
a{f}/
s f
Python 284
from random import*
C=choice
A=map(chr,range(65,91)+[32])
s=[C(A)for i in[0]*28]
N=x=0
while N!=28:N,s=max((len([i for i,j in zip(X,"METHINKS IT IS LIKE A WEASEL")if i==j]),X)for X in[[c if random()<.95 else C(A)for c in s]for i in[0]*100]);print`x`+":",''.join(s),"-- score:",N;x+=1
C# - 436
namespace System.Linq{class W{static void Main(){var r=new Random();
Func<char>c=()=>(char)(r.Next(33,60)%59+32);var s="";
while(s.Length<28)s+=c();var a="METHINKS IT IS LIKE A WEASEL";int b=0;
while (s!=a){int m=-1;var f=s;for(int i=0;i<100;i++){
var l=string.Join("",s.Select(j=>(r.Next(20)!=0?j:c()).ToString()));
int o=Enumerable.Range(0,28).Sum(j=>l[j]==a[j]?1:0);if(o>m){f=l;m=o;}}
Console.WriteLine(b+++": "+(s=f)+" -- score: "+m);}}}}
K, 173 167
o:"METHINKS IT IS LIKE A WEASEL"
i:0;{~x~o}{-1($i),": ",(r:a@*&b=c)," -- score: ",$c:max@b:+/'o=/:a:{x{if[0~*1?20;x[y]:*1?s];x}/!#x}'100#,x;i+:1;r}/28?s:"c"$32,65+!26;
/
0: FQRZPHACDIBHZOUUCYKKFBJWVNVI -- score: 1
1: FQRZP ACDITHCOUUCYKKFBJWVNVI -- score: 2
2: FQRZP AFDIT COUUCYKKFBJWVNVI -- score: 3
...
51: METHINKS IT IS LIKECA WEASEL -- score: 27
52: METHINKS IT IS LIKECA WEASEL -- score: 27
53: METHINKS IT IS LIKE A WEASEL -- score: 28
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: setCto 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: setTto 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 each1means 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 fromcwhose score is equal tos(the maximum), and store it incagain.⎕←(⍕⍺),':'c'-- score:',s: print the generation in the given format (⍺is current generation,cis current best string,sis 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
Ruby - 410
#!/usr/bin/env ruby
C,RC=[32]+(65..90).to_a,->{C[rand(27)].chr}
T,CO,CH,OU,s,sc,a,aa,z,TR="METHINKS IT IS LIKE A WEASEL",->x{a=0;(0...28).each{|z|a+=1 if x[z]==T[z]};a},->{a[aa.rindex(sc)]},->x,y{print x;print " Score: ";puts y},(0...28).map{RC[]}.join,0,[0],[0],0,->{rand(20)==0}
until sc==28
a=[s]*100;aa=[0]*100;(0...100).each{|x|(0...28).each{|y|a[x][y]=RC[] if TR[]};z=CO[a[x]];aa[x]=CO[a[x]];OU[a[x],z]};sc=aa.max;s=CH[] end
Edit* It's currently failing (for some reason a[any] is being set to 0 (type=>fixnum)). However, the actual design is right, I just need to find the bug causing this to happen (it's very mysterious)
Lua 5.1 (502)
The minimised version:
s,t,b,c,i,q,a,d,f="ABCDFGHJYUEGKSHNCOLPQIEJUSNC","METHINKS IT IS LIKE A WEASEL",1,math.random,table.insert,1,string.sub,100,28 while q~=f do r,p={},{} for x=1,d do i(r,s) i(p,0) e="" for o=1,f do if c(1,20)==1 then if c(1,27)==1 then e=e.." " else e=e..string.char(c(65,90)) end else e=e..a(r[x],o,o) end end r[x]=e for y=1,f do if a(r[x],y,y)==a(t,y,y) then p[x]=p[x]+1 end end if p[x]==f then s=r[x] end end for x=1,d do if p[x]>=q then s,q=r[x],p[x] end end print(b..":",s,"-- score: "..q) b=b+1 end
and the easier to read version (with comments!):
s,t,b,c,i,q,a,d,f="ABCDFGHJYUEGKSHNCOLPQIEJUSNC","METHINKS IT IS LIKE A WEASEL",1,math.random,table.insert,1,string.sub,100,28
--s=random string, t=target, b=counter, c=reference to math.random, i=reference to table.insert, q=top score,a=reference to string.sub, d=constant (100), f=constant (28)
while q~=f do
r,p={},{}
for x=1,d do --add 100 copies to the table of strings
i(r,s)
i(p,0)
e=""
for o=1,f do --for each character in string
if c(1,20)==1 then -- 5% chance
if c(1,27)==1 then e=e.." " else e=e..string.char(c(65,90)) end --set it to an ASCII char between 65 and 90 (A-Z) or a space character
else
e=e..a(r[x],o,o)
end
end
r[x]=e --current string = mutations
for y=1,f do
if a(r[x],y,y)==a(t,y,y) then p[x]=p[x]+1 end
end --for each char increment score if it is correct
if p[x]==f then
s=r[x]
end --if 28 then final string is this!
end
for x=1,d do
if p[x]>=q then s,q=r[x],p[x] end --if this is the highest score so far, then make the string equal to this
end
print(b..":",s,"-- score: "..q) --print it!
b=b+1 --add one to the counter!
end
To be honest even though this definitely won't win, I was just glad to find and minimise a reasonably short solution for this problem! (emphasis on reasonably) :p
PHP 442
<? function r(){$n=rand(65,91);if($n==91) return ' ';else return chr($n);}function s($s){$c=0;$t='METHINKS IT IS LIKE A WEASEL';for($i=0;$i<28;$i++) if($s[$i]==$t[$i]) $c++;return $c;}function m($s){for($i=0;$i<28;$i++) if(rand(0,99)<5) $s[$i]=r();return $s;}$s='';for($i=0;$i<28;$i++) $s.=r();for($i=0;;$i++){$l=s($s);printf("%2d: %s -- score: %d\n",$i,$s,$l);if($l==28) break;$x=$s;for($j=0;$j<100;$j++){$t=m($s);if(s($t)>$l) $x=$t;}$s=$x;}
Readbly:
<?
//random char
function r(){
$n=rand(65,91);
if($n==91) return ' ';
else return chr($n);
}
//score
function s($s){
$c=0;
$t='METHINKS IT IS LIKE A WEASEL';
for($i=0;$i<28;$i++)
if($s[$i]==$t[$i]) $c++;
return $c;
}
//mutate
function m($s){
for($i=0;$i<28;$i++)
if(rand(0,99)<5) $s[$i]=r();
return $s;
}
$s='';
for($i=0;$i<28;$i++) $s.=r();
for($i=0;;$i++){
$l=s($s);
printf("%2d: %s -- score: %d\n",$i,$s,$l);
if($l==28) break;
$x=$s;
for($j=0;$j<100;$j++){
$t=m($s);
if(s($t)>$l) $x=$t;
}
$s=$x;
}