33 lines
1.6 KiB
Prolog
33 lines
1.6 KiB
Prolog
target("METHINKS IT IS LIKE A WEASEL").
|
|
|
|
rndAlpha(64, 32). % Generate a single random character
|
|
rndAlpha(P, P). % 32 is a space, and 65->90 are upper case
|
|
rndAlpha(Ch) :- random(N), P is truncate(64+(N*27)), !, rndAlpha(P, Ch).
|
|
|
|
rndTxt(0, []). % Generate some random text (fixed length)
|
|
rndTxt(Len, [H|T]) :- succ(L, Len), rndAlpha(H), !, rndTxt(L, T).
|
|
|
|
score([], [], Score, Score). % Score a generated mutation (count diffs)
|
|
score([Ht|Tt], [Ht|Tp], C, Score) :- !, score(Tt, Tp, C, Score).
|
|
score([_|Tt], [_|Tp], C, Score) :- succ(C, N), !, score(Tt, Tp, N, Score).
|
|
score(Txt, Score, Target) :- !, score(Target, Txt, 0, Score).
|
|
|
|
mutate(_, [], []). % mutate(Probability, Input, Output)
|
|
mutate(P, [H|Txt], [H|Mut]) :- random(R), R < P, !, mutate(P, Txt, Mut).
|
|
mutate(P, [_|Txt], [M|Mut]) :- rndAlpha(M), !, mutate(P, Txt, Mut).
|
|
|
|
weasel(Tries, _, _, mutation(0, Result)) :- % No differences=success
|
|
format('~w~4|:~w~3| - ~s\n', [Tries, 0, Result]).
|
|
weasel(Tries, Chance, Target, mutation(S, Value)) :- % output progress
|
|
format('~w~4|:~w~3| - ~s\n', [Tries, S, Value]), !, % and call again
|
|
weasel(Tries, Chance, Target, Value).
|
|
weasel(Tries, Chance, Target, Start) :-
|
|
findall(mutation(S,M), % Generate 30 mutations, select the best.
|
|
(between(1, 30, _), mutate(Chance, Start, M), score(M,S,Target)),
|
|
Mutations), % List of 30 mutations and their scores
|
|
sort(Mutations, [Best|_]), succ(Tries, N),
|
|
!, weasel(N, Chance, Target, Best).
|
|
weasel :- % Chance->probability for a mutation, T=Target, Start=initial text
|
|
target(T), length(T, Len), rndTxt(Len, Start), Chance is 1 - (1/(Len+1)),
|
|
!, weasel(0, Chance, T, Start).
|