52 lines
1.6 KiB
Plaintext
52 lines
1.6 KiB
Plaintext
fitness = proc (s, t: string) returns (int)
|
|
f: int := 0
|
|
for i: int in int$from_to(1,string$size(s)) do
|
|
if s[i] ~= t[i] then f := f-1 end
|
|
end
|
|
return(f)
|
|
end fitness
|
|
|
|
mutate = proc (mut: int, s: string) returns (string)
|
|
own charset: string := " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
out: array[char] := array[char]$predict(1,string$size(s))
|
|
for c: char in string$chars(s) do
|
|
if random$next(10000) < mut then
|
|
c := charset[1+random$next(string$size(charset))]
|
|
end
|
|
array[char]$addh(out,c)
|
|
end
|
|
return(string$ac2s(out))
|
|
end mutate
|
|
|
|
weasel = iter (mut, c: int, tgt: string) yields (string)
|
|
own charset: string := " ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
|
start: array[char] := array[char]$[]
|
|
for i: int in int$from_to(1,string$size(tgt)) do
|
|
array[char]$addh(start,charset[1+random$next(string$size(charset))])
|
|
end
|
|
cur: string := string$ac2s(start)
|
|
while true do
|
|
yield(cur)
|
|
if cur = tgt then break end
|
|
best: string := cur
|
|
best_fitness: int := fitness(cur, tgt)
|
|
for i: int in int$from_to(2,c) do
|
|
next: string := mutate(mut, cur)
|
|
next_fitness: int := fitness(next, tgt)
|
|
if best_fitness <= next_fitness then
|
|
best, best_fitness := next, next_fitness
|
|
end
|
|
end
|
|
cur := best
|
|
end
|
|
end weasel
|
|
|
|
start_up = proc ()
|
|
d: date := now()
|
|
random$seed(d.second + 60*(d.minute + 60*d.hour))
|
|
po: stream := stream$primary_output()
|
|
for m: string in weasel(100, 1000, "METHINKS IT IS LIKE A WEASEL") do
|
|
stream$putl(po, m)
|
|
end
|
|
end start_up
|